Ok, first of all, when you want help, posting data as just plain ol' text doesn't help us help you . You need to make the data "readily consumable" so that we can provide you with tested code. Sure, it only takes a couple of minutes to change your text into actual test data but a lot of us answer a lot of posts on a lot of forums and anything you can do to make it easier will mean that your post gets better attention faster.
Here's one of many ways you could have posted the data to make our lives a bit easier especially for the somewhat detailed question you asked. You might also want to break out a map and find out where Dallas is before a whole lot of Texans come looking for ya. 
--===== Do this in a nice, safe place that everyone has
USE tempdb
;
--===== If the Test Table already exists,
-- drop it to make reruns in SSMS easier.
IF OBJECT_ID('dbo.Locations','U') IS NOT NULL
DROP TABLE dbo.Locations
;
--===== Create and populate the test table on-the-fly.
SELECT *
INTO dbo.Locations
FROM (
SELECT 1,0,1,'Region' UNION ALL
SELECT 2,0,1,'Country' UNION ALL
SELECT 3,0,1,'State_Province' UNION ALL
SELECT 4,0,1,'Localities' UNION ALL
SELECT 5,1,0,'US' UNION ALL
SELECT 6,2,5,'USA' UNION ALL
SELECT 7,3,6,'Albama' UNION ALL
SELECT 8,4,7,'Atlanta' UNION ALL
SELECT 9,3,6,'Texas' UNION ALL
SELECT 10,4,7,'Dallas' --BWAA-HAAA!!! Wait 'til the folks in Dallas find out you put them in 'Bama!!! ;-)
) testdata ([Key],DomainID, ParentID, Value)
;
Next, comes the function. Notice that it does NOT have a table definition and it does NOT have a BEGIN in it. Those are the traits of a high performance iTVF instead of like the mTVF you wrote. Also note the use of an rCTE (Recursive CTE) in this case. Those are frequently slower than a WHILE loop but we had to use one to keep from using an mTVF. If you really want this to be fast, then we should add the Bowers of "Nested Sets" to your table and use those for the hierarchical traversal instead of recalculating over and over that which will only change once in a Blue Moon.
Here's the function. It's got usage examples in the header.
CREATE FUNCTION dbo.GetLocations
/******************************************************************************
Purpose:
Given a [Key] from the "Locations" table, return the [Key] for the Region,
Country, State_Province, and Locality. If the entry point into the hierarchy
is above the Locality level, return nulls below the entry point.
Usage Examples:
--===== Single value example.
DECLARE @pKeyToFind INT;
SELECT @pKeyToFind = 10;
SELECT KeyToFind = @pKeyToFind, * FROM dbo.GetLocations(@pKeyToFind)
;
--===== Table example
SELECT KeyToFind = st.SomeKey
,ca.*
FROM dbo.SomeTable st
CROSS APPLY dbo.GetLocations(st.SomeKey) ca
;
Rev 00 - Jeff Moden - 22 Dec 2015
- Reference:
http://forums.sqlteam.com/t/table-valued-function-performance-issue/4552
******************************************************************************/
--===== Define the IO for this itVF function.
(@pKeyToFind INT)
RETURNS TABLE WITH SCHEMABINDING AS
RETURN WITH
cteHierarchyUpline AS
(--==== Get key row at the bottom of the upline
SELECT [Key], DomainID, ParentID, Value
FROM dbo.Locations
WHERE [KEY] = @pKeyToFind
UNION ALL -- And now traverse the upline
SELECT tbl.[Key], tbl.DomainID, tbl.ParentID, tbl.Value
FROM cteHierarchyUpline cte
JOIN dbo.Locations tbl
ON tbl.[Key] = cte.ParentID
)--==== This CROSSTAB creates the output you want
SELECT Region = MAX(CASE WHEN DomainID = 1 THEN [Key] ELSE NULL END)
,Country = MAX(CASE WHEN DomainID = 2 THEN [Key] ELSE NULL END)
,State_Province = MAX(CASE WHEN DomainID = 3 THEN [Key] ELSE NULL END)
,Locality = MAX(CASE WHEN DomainID = 4 THEN [Key] ELSE NULL END)
FROM cteHierarchyUpline
;
GO
The other thing to notice is that, if your hierarchy is structured correctly, there will always be only one node per level in the upline search, which makes this perfect for a CROSSTAB (the MAX/CASE stuff), which is usually faster than PIVOT.
If you have any additional questions on this, please send beer. I already have enough pretzels. 