Here's a VB.NET adaptation of @Jeff Fritz's solution. It does the same thing but includes all controls located anywhere in the solution. (Our architecture uses modules that can be incorporated as SVN externals, so this provides a very nice way to make sure that the host application is aware of all modules' controls.)
Sub RegisterUserControls()
Dim Config As Configuration = WebConfigurationManager.OpenWebConfiguration("~/")
Dim WebSection As PagesSection = TryCast(Config.GetSection("system.web/pages"), PagesSection)
Dim ToRemove As List(Of TagPrefixInfo) = ( _
From t As TagPrefixInfo In WebSection.Controls _
Select t Where t.Source IsNot Nothing AndAlso t.Source.EndsWith(".ascx") _
).ToList
For Each t As TagPrefixInfo In ToRemove
WebSection.Controls.Remove(t)
Next
Dim SiteRoot As New DirectoryInfo(Server.MapPath("~"))
For Each f As FileInfo In SiteRoot.GetFiles("*.ascx", SearchOption.AllDirectories)
Dim Source As String = Path.Combine("~/", f.FullName.Replace(SiteRoot.FullName, "")).Replace("\", "/")
Dim TagName As String = Path.GetFileNameWithoutExtension(f.Name)
Dim NewTag As New TagPrefixInfo( _
tagPrefix:="YOURPREFIX", _
nameSpace:=Nothing, _
assembly:=Nothing, _
TagName:=TagName, _
Source:=Source)
WebSection.Controls.Add(NewTag)
Next
Config.Save(ConfigurationSaveMode.Modified)
ConfigurationManager.RefreshSection("system.web/pages")
End Sub
(Of course you would reference this in Application_Start like Jeff did.)