xref: /llvm-project/llvm/lib/Transforms/Utils/DemoteRegToStack.cpp (revision fdaad738753cde2bba6480c2ee5d1e9fb45064b9)
1 //===- DemoteRegToStack.cpp - Move a virtual register to the stack --------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/ADT/DenseMap.h"
10 #include "llvm/Analysis/CFG.h"
11 #include "llvm/IR/Function.h"
12 #include "llvm/IR/Instructions.h"
13 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
14 #include "llvm/Transforms/Utils/Local.h"
15 using namespace llvm;
16 
17 /// DemoteRegToStack - This function takes a virtual register computed by an
18 /// Instruction and replaces it with a slot in the stack frame, allocated via
19 /// alloca.  This allows the CFG to be changed around without fear of
20 /// invalidating the SSA information for the value.  It returns the pointer to
21 /// the alloca inserted to create a stack slot for I.
22 AllocaInst *llvm::DemoteRegToStack(Instruction &I, bool VolatileLoads,
23                                    std::optional<BasicBlock::iterator> AllocaPoint) {
24   if (I.use_empty()) {
25     I.eraseFromParent();
26     return nullptr;
27   }
28 
29   Function *F = I.getParent()->getParent();
30   const DataLayout &DL = F->getParent()->getDataLayout();
31 
32   // Create a stack slot to hold the value.
33   AllocaInst *Slot;
34   if (AllocaPoint) {
35     Slot = new AllocaInst(I.getType(), DL.getAllocaAddrSpace(), nullptr,
36                           I.getName()+".reg2mem", *AllocaPoint);
37   } else {
38     Slot = new AllocaInst(I.getType(), DL.getAllocaAddrSpace(), nullptr,
39                           I.getName() + ".reg2mem", F->getEntryBlock().begin());
40   }
41 
42   // We cannot demote invoke instructions to the stack if their normal edge
43   // is critical. Therefore, split the critical edge and create a basic block
44   // into which the store can be inserted.
45   if (InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
46     if (!II->getNormalDest()->getSinglePredecessor()) {
47       unsigned SuccNum = GetSuccessorNumber(II->getParent(), II->getNormalDest());
48       assert(isCriticalEdge(II, SuccNum) && "Expected a critical edge!");
49       BasicBlock *BB = SplitCriticalEdge(II, SuccNum);
50       assert(BB && "Unable to split critical edge.");
51       (void)BB;
52     }
53   } else if (CallBrInst *CBI = dyn_cast<CallBrInst>(&I)) {
54     for (int i = 0; i < CBI->getNumSuccessors(); i++) {
55       auto *Succ = CBI->getSuccessor(i);
56       if (!Succ->getSinglePredecessor()) {
57         assert(isCriticalEdge(II, i) && "Expected a critical edge!");
58         BasicBlock *BB = SplitCriticalEdge(II, i);
59         assert(BB && "Unable to split critical edge.");
60       }
61     }
62   }
63 
64   // Change all of the users of the instruction to read from the stack slot.
65   while (!I.use_empty()) {
66     Instruction *U = cast<Instruction>(I.user_back());
67     if (PHINode *PN = dyn_cast<PHINode>(U)) {
68       // If this is a PHI node, we can't insert a load of the value before the
69       // use.  Instead insert the load in the predecessor block corresponding
70       // to the incoming value.
71       //
72       // Note that if there are multiple edges from a basic block to this PHI
73       // node that we cannot have multiple loads. The problem is that the
74       // resulting PHI node will have multiple values (from each load) coming in
75       // from the same block, which is illegal SSA form. For this reason, we
76       // keep track of and reuse loads we insert.
77       DenseMap<BasicBlock*, Value*> Loads;
78       for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
79         if (PN->getIncomingValue(i) == &I) {
80           Value *&V = Loads[PN->getIncomingBlock(i)];
81           if (!V) {
82             // Insert the load into the predecessor block
83             V = new LoadInst(I.getType(), Slot, I.getName() + ".reload",
84                              VolatileLoads,
85                              PN->getIncomingBlock(i)->getTerminator()->getIterator());
86             Loads[PN->getIncomingBlock(i)] = V;
87           }
88           PN->setIncomingValue(i, V);
89         }
90 
91     } else {
92       // If this is a normal instruction, just insert a load.
93       Value *V = new LoadInst(I.getType(), Slot, I.getName() + ".reload",
94                               VolatileLoads, U->getIterator());
95       U->replaceUsesOfWith(&I, V);
96     }
97   }
98 
99   // Insert stores of the computed value into the stack slot. We have to be
100   // careful if I is an invoke instruction, because we can't insert the store
101   // AFTER the terminator instruction.
102   BasicBlock::iterator InsertPt;
103   if (!I.isTerminator()) {
104     InsertPt = ++I.getIterator();
105     // Don't insert before PHI nodes or landingpad instrs.
106     for (; isa<PHINode>(InsertPt) || InsertPt->isEHPad(); ++InsertPt)
107       if (isa<CatchSwitchInst>(InsertPt))
108         break;
109     if (isa<CatchSwitchInst>(InsertPt)) {
110       for (BasicBlock *Handler : successors(&*InsertPt))
111         new StoreInst(&I, Slot, Handler->getFirstInsertionPt());
112       return Slot;
113     }
114   } else if (InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
115     InsertPt = II->getNormalDest()->getFirstInsertionPt();
116   } else if (CallBrInst *CBI = dyn_cast<CallBrInst>(&I)) {
117     for (BasicBlock *Succ : successors(CBI))
118       new StoreInst(CBI, Slot, Succ->getFirstInsertionPt());
119     return Slot;
120   } else {
121     llvm_unreachable("Unsupported terminator for Reg2Mem");
122   }
123 
124   new StoreInst(&I, Slot, InsertPt);
125   return Slot;
126 }
127 
128 /// DemotePHIToStack - This function takes a virtual register computed by a PHI
129 /// node and replaces it with a slot in the stack frame allocated via alloca.
130 /// The PHI node is deleted. It returns the pointer to the alloca inserted.
131 AllocaInst *llvm::DemotePHIToStack(PHINode *P, std::optional<BasicBlock::iterator> AllocaPoint) {
132   if (P->use_empty()) {
133     P->eraseFromParent();
134     return nullptr;
135   }
136 
137   const DataLayout &DL = P->getModule()->getDataLayout();
138 
139   // Create a stack slot to hold the value.
140   AllocaInst *Slot;
141   if (AllocaPoint) {
142     Slot = new AllocaInst(P->getType(), DL.getAllocaAddrSpace(), nullptr,
143                           P->getName()+".reg2mem", *AllocaPoint);
144   } else {
145     Function *F = P->getParent()->getParent();
146     Slot = new AllocaInst(P->getType(), DL.getAllocaAddrSpace(), nullptr,
147                           P->getName() + ".reg2mem",
148                           F->getEntryBlock().begin());
149   }
150 
151   // Iterate over each operand inserting a store in each predecessor.
152   for (unsigned i = 0, e = P->getNumIncomingValues(); i < e; ++i) {
153     if (InvokeInst *II = dyn_cast<InvokeInst>(P->getIncomingValue(i))) {
154       assert(II->getParent() != P->getIncomingBlock(i) &&
155              "Invoke edge not supported yet"); (void)II;
156     }
157     new StoreInst(P->getIncomingValue(i), Slot,
158                   P->getIncomingBlock(i)->getTerminator()->getIterator());
159   }
160 
161   // Insert a load in place of the PHI and replace all uses.
162   BasicBlock::iterator InsertPt = P->getIterator();
163   // Don't insert before PHI nodes or landingpad instrs.
164   for (; isa<PHINode>(InsertPt) || InsertPt->isEHPad(); ++InsertPt)
165     if (isa<CatchSwitchInst>(InsertPt))
166       break;
167   if (isa<CatchSwitchInst>(InsertPt)) {
168     // We need a separate load before each actual use of the PHI
169     SmallVector<Instruction *, 4> Users;
170     for (User *U : P->users()) {
171       Instruction *User = cast<Instruction>(U);
172       Users.push_back(User);
173     }
174     for (Instruction *User : Users) {
175       Value *V =
176           new LoadInst(P->getType(), Slot, P->getName() + ".reload", User->getIterator());
177       User->replaceUsesOfWith(P, V);
178     }
179   } else {
180     Value *V =
181         new LoadInst(P->getType(), Slot, P->getName() + ".reload", InsertPt);
182     P->replaceAllUsesWith(V);
183   }
184   // Delete PHI.
185   P->eraseFromParent();
186   return Slot;
187 }
188