@@ -741,6 +741,13 @@ namespace {
741
741
742
742
// / Promote memory to registers
743
743
class MemoryToRegisters {
744
+ // / Lazily initialized map from DomTreeNode to DomTreeLevel.
745
+ // /
746
+ // / DomTreeLevelMap is a DenseMap implying that if we initialize it, we always
747
+ // / will initialize a heap object with 64 objects. Thus by using an optional,
748
+ // / computing this lazily, we only do this if we actually need to do so.
749
+ Optional<DomTreeLevelMap> domTreeLevels;
750
+
744
751
// / The function that we are optimizing.
745
752
SILFunction &f;
746
753
@@ -751,6 +758,32 @@ class MemoryToRegisters {
751
758
// / promotion.
752
759
SILBuilderContext ctx;
753
760
761
+ // / Returns the dom tree levels for the current function. Computes these
762
+ // / lazily.
763
+ DomTreeLevelMap &getDomTreeLevels () {
764
+ // If we already computed our levels, just return it.
765
+ if (auto &levels = domTreeLevels) {
766
+ return *levels;
767
+ }
768
+
769
+ // Otherwise, emplace the map and compute it.
770
+ domTreeLevels.emplace ();
771
+ auto &levels = *domTreeLevels;
772
+ SmallVector<DomTreeNode *, 32 > worklist;
773
+ DomTreeNode *rootNode = domInfo->getRootNode ();
774
+ levels[rootNode] = 0 ;
775
+ worklist.push_back (rootNode);
776
+ while (!worklist.empty ()) {
777
+ DomTreeNode *domNode = worklist.pop_back_val ();
778
+ unsigned childLevel = levels[domNode] + 1 ;
779
+ for (auto *childNode : domNode->children ()) {
780
+ levels[childNode] = childLevel;
781
+ worklist.push_back (childNode);
782
+ }
783
+ }
784
+ return *domTreeLevels;
785
+ }
786
+
754
787
// / Check if the AllocStackInst \p ASI is only written into.
755
788
bool isWriteOnlyAllocation (AllocStackInst *asi);
756
789
@@ -763,8 +796,7 @@ class MemoryToRegisters {
763
796
// / Attempt to promote the specified stack allocation, returning true if so
764
797
// / or false if not. On success, all uses of the AllocStackInst have been
765
798
// / removed, but the ASI itself is still in the program.
766
- bool promoteSingleAllocation (AllocStackInst *asi,
767
- DomTreeLevelMap &domTreeLevels);
799
+ bool promoteSingleAllocation (AllocStackInst *asi);
768
800
769
801
public:
770
802
// / C'tor
@@ -1001,30 +1033,11 @@ void MemoryToRegisters::removeSingleBlockAllocation(AllocStackInst *asi) {
1001
1033
}
1002
1034
}
1003
1035
1004
- // / Compute the dominator tree levels for domInfo.
1005
- static void computeDomTreeLevels (DominanceInfo *domInfo,
1006
- DomTreeLevelMap &domTreeLevels) {
1007
- // TODO: This should happen once per function.
1008
- SmallVector<DomTreeNode *, 32 > worklist;
1009
- DomTreeNode *rootNode = domInfo->getRootNode ();
1010
- domTreeLevels[rootNode] = 0 ;
1011
- worklist.push_back (rootNode);
1012
- while (!worklist.empty ()) {
1013
- DomTreeNode *domNode = worklist.pop_back_val ();
1014
- unsigned childLevel = domTreeLevels[domNode] + 1 ;
1015
- for (auto *childNode : domNode->children ()) {
1016
- domTreeLevels[childNode] = childLevel;
1017
- worklist.push_back (childNode);
1018
- }
1019
- }
1020
- }
1021
-
1022
1036
// / Attempt to promote the specified stack allocation, returning true if so
1023
1037
// / or false if not. On success, this returns true and usually drops all of the
1024
1038
// / uses of the AllocStackInst, but never deletes the ASI itself. Callers
1025
1039
// / should check to see if the ASI is dead after this and remove it if so.
1026
- bool MemoryToRegisters::promoteSingleAllocation (
1027
- AllocStackInst *alloc, DomTreeLevelMap &domTreeLevels) {
1040
+ bool MemoryToRegisters::promoteSingleAllocation (AllocStackInst *alloc) {
1028
1041
LLVM_DEBUG (llvm::dbgs () << " *** Memory to register looking at: " << *alloc);
1029
1042
++NumAllocStackFound;
1030
1043
@@ -1064,7 +1077,9 @@ bool MemoryToRegisters::promoteSingleAllocation(
1064
1077
1065
1078
LLVM_DEBUG (llvm::dbgs () << " *** Need to insert BB arguments for " << *alloc);
1066
1079
1067
- // Promote this allocation.
1080
+ // Promote this allocation, lazily computing dom tree levels for this function
1081
+ // if we have not done so yet.
1082
+ auto &domTreeLevels = getDomTreeLevels ();
1068
1083
StackAllocationPromoter (alloc, domInfo, domTreeLevels, ctx).run ();
1069
1084
1070
1085
// Make sure that all of the allocations were promoted into registers.
@@ -1080,10 +1095,6 @@ bool MemoryToRegisters::run() {
1080
1095
if (f.getModule ().getOptions ().VerifyAll )
1081
1096
f.verifyCriticalEdges ();
1082
1097
1083
- // Compute dominator tree node levels for the function.
1084
- DomTreeLevelMap domTreeLevels;
1085
- computeDomTreeLevels (domInfo, domTreeLevels);
1086
-
1087
1098
for (auto &block : f) {
1088
1099
auto ii = block.begin (), ie = block.end ();
1089
1100
while (ii != ie) {
@@ -1094,7 +1105,7 @@ bool MemoryToRegisters::run() {
1094
1105
continue ;
1095
1106
}
1096
1107
1097
- bool promoted = promoteSingleAllocation (asi, domTreeLevels );
1108
+ bool promoted = promoteSingleAllocation (asi);
1098
1109
++ii;
1099
1110
if (promoted) {
1100
1111
if (asi->use_empty ())
0 commit comments