1f22ef01cSRoman Divacky //===- DemoteRegToStack.cpp - Move a virtual register to the stack --------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky 
10dff0c46cSDimitry Andric #include "llvm/ADT/DenseMap.h"
11f785676fSDimitry Andric #include "llvm/Analysis/CFG.h"
124ba319b5SDimitry Andric #include "llvm/Transforms/Utils/Local.h"
13139f7f9bSDimitry Andric #include "llvm/IR/Function.h"
14139f7f9bSDimitry Andric #include "llvm/IR/Instructions.h"
15139f7f9bSDimitry Andric #include "llvm/IR/Type.h"
16db17bf38SDimitry Andric #include "llvm/Transforms/Utils/BasicBlockUtils.h"
17f22ef01cSRoman Divacky using namespace llvm;
18f22ef01cSRoman Divacky 
19f22ef01cSRoman Divacky /// DemoteRegToStack - This function takes a virtual register computed by an
20f22ef01cSRoman Divacky /// Instruction and replaces it with a slot in the stack frame, allocated via
21f22ef01cSRoman Divacky /// alloca.  This allows the CFG to be changed around without fear of
22f22ef01cSRoman Divacky /// invalidating the SSA information for the value.  It returns the pointer to
23f22ef01cSRoman Divacky /// the alloca inserted to create a stack slot for I.
DemoteRegToStack(Instruction & I,bool VolatileLoads,Instruction * AllocaPoint)24f22ef01cSRoman Divacky AllocaInst *llvm::DemoteRegToStack(Instruction &I, bool VolatileLoads,
25f22ef01cSRoman Divacky                                    Instruction *AllocaPoint) {
26f22ef01cSRoman Divacky   if (I.use_empty()) {
27f22ef01cSRoman Divacky     I.eraseFromParent();
2891bc56edSDimitry Andric     return nullptr;
29f22ef01cSRoman Divacky   }
30f22ef01cSRoman Divacky 
317a7e6055SDimitry Andric   Function *F = I.getParent()->getParent();
327a7e6055SDimitry Andric   const DataLayout &DL = F->getParent()->getDataLayout();
337a7e6055SDimitry Andric 
34f22ef01cSRoman Divacky   // Create a stack slot to hold the value.
35f22ef01cSRoman Divacky   AllocaInst *Slot;
36f22ef01cSRoman Divacky   if (AllocaPoint) {
377a7e6055SDimitry Andric     Slot = new AllocaInst(I.getType(), DL.getAllocaAddrSpace(), nullptr,
38f22ef01cSRoman Divacky                           I.getName()+".reg2mem", AllocaPoint);
39f22ef01cSRoman Divacky   } else {
407a7e6055SDimitry Andric     Slot = new AllocaInst(I.getType(), DL.getAllocaAddrSpace(), nullptr,
417a7e6055SDimitry Andric                           I.getName() + ".reg2mem", &F->getEntryBlock().front());
42f22ef01cSRoman Divacky   }
43f22ef01cSRoman Divacky 
44ff0cc061SDimitry Andric   // We cannot demote invoke instructions to the stack if their normal edge
45ff0cc061SDimitry Andric   // is critical. Therefore, split the critical edge and create a basic block
46ff0cc061SDimitry Andric   // into which the store can be inserted.
47ff0cc061SDimitry Andric   if (InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
48ff0cc061SDimitry Andric     if (!II->getNormalDest()->getSinglePredecessor()) {
49ff0cc061SDimitry Andric       unsigned SuccNum = GetSuccessorNumber(II->getParent(), II->getNormalDest());
50ff0cc061SDimitry Andric       assert(isCriticalEdge(II, SuccNum) && "Expected a critical edge!");
51ff0cc061SDimitry Andric       BasicBlock *BB = SplitCriticalEdge(II, SuccNum);
52ff0cc061SDimitry Andric       assert(BB && "Unable to split critical edge.");
53ff0cc061SDimitry Andric       (void)BB;
54ff0cc061SDimitry Andric     }
55ff0cc061SDimitry Andric   }
56ff0cc061SDimitry Andric 
57dff0c46cSDimitry Andric   // Change all of the users of the instruction to read from the stack slot.
58f22ef01cSRoman Divacky   while (!I.use_empty()) {
5991bc56edSDimitry Andric     Instruction *U = cast<Instruction>(I.user_back());
60f22ef01cSRoman Divacky     if (PHINode *PN = dyn_cast<PHINode>(U)) {
61f22ef01cSRoman Divacky       // If this is a PHI node, we can't insert a load of the value before the
62dff0c46cSDimitry Andric       // use.  Instead insert the load in the predecessor block corresponding
63f22ef01cSRoman Divacky       // to the incoming value.
64f22ef01cSRoman Divacky       //
65f22ef01cSRoman Divacky       // Note that if there are multiple edges from a basic block to this PHI
66dff0c46cSDimitry Andric       // node that we cannot have multiple loads. The problem is that the
67dff0c46cSDimitry Andric       // resulting PHI node will have multiple values (from each load) coming in
68dff0c46cSDimitry Andric       // from the same block, which is illegal SSA form. For this reason, we
69dff0c46cSDimitry Andric       // keep track of and reuse loads we insert.
70dff0c46cSDimitry Andric       DenseMap<BasicBlock*, Value*> Loads;
71f22ef01cSRoman Divacky       for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
72f22ef01cSRoman Divacky         if (PN->getIncomingValue(i) == &I) {
73f22ef01cSRoman Divacky           Value *&V = Loads[PN->getIncomingBlock(i)];
7491bc56edSDimitry Andric           if (!V) {
75f22ef01cSRoman Divacky             // Insert the load into the predecessor block
76f22ef01cSRoman Divacky             V = new LoadInst(Slot, I.getName()+".reload", VolatileLoads,
77f22ef01cSRoman Divacky                              PN->getIncomingBlock(i)->getTerminator());
78f22ef01cSRoman Divacky           }
79f22ef01cSRoman Divacky           PN->setIncomingValue(i, V);
80f22ef01cSRoman Divacky         }
81f22ef01cSRoman Divacky 
82f22ef01cSRoman Divacky     } else {
83f22ef01cSRoman Divacky       // If this is a normal instruction, just insert a load.
84f22ef01cSRoman Divacky       Value *V = new LoadInst(Slot, I.getName()+".reload", VolatileLoads, U);
85f22ef01cSRoman Divacky       U->replaceUsesOfWith(&I, V);
86f22ef01cSRoman Divacky     }
87f22ef01cSRoman Divacky   }
88f22ef01cSRoman Divacky 
89f22ef01cSRoman Divacky   // Insert stores of the computed value into the stack slot. We have to be
90dff0c46cSDimitry Andric   // careful if I is an invoke instruction, because we can't insert the store
91dff0c46cSDimitry Andric   // AFTER the terminator instruction.
92f22ef01cSRoman Divacky   BasicBlock::iterator InsertPt;
93*b5893f02SDimitry Andric   if (!I.isTerminator()) {
947d523365SDimitry Andric     InsertPt = ++I.getIterator();
957d523365SDimitry Andric     for (; isa<PHINode>(InsertPt) || InsertPt->isEHPad(); ++InsertPt)
96dff0c46cSDimitry Andric       /* empty */;   // Don't insert before PHI nodes or landingpad instrs.
97ff0cc061SDimitry Andric   } else {
98ff0cc061SDimitry Andric     InvokeInst &II = cast<InvokeInst>(I);
99ff0cc061SDimitry Andric     InsertPt = II.getNormalDest()->getFirstInsertionPt();
100ff0cc061SDimitry Andric   }
101f22ef01cSRoman Divacky 
1027d523365SDimitry Andric   new StoreInst(&I, Slot, &*InsertPt);
103f22ef01cSRoman Divacky   return Slot;
104f22ef01cSRoman Divacky }
105f22ef01cSRoman Divacky 
106dff0c46cSDimitry Andric /// DemotePHIToStack - This function takes a virtual register computed by a PHI
107dff0c46cSDimitry Andric /// node and replaces it with a slot in the stack frame allocated via alloca.
108dff0c46cSDimitry Andric /// The PHI node is deleted. It returns the pointer to the alloca inserted.
DemotePHIToStack(PHINode * P,Instruction * AllocaPoint)109f22ef01cSRoman Divacky AllocaInst *llvm::DemotePHIToStack(PHINode *P, Instruction *AllocaPoint) {
110f22ef01cSRoman Divacky   if (P->use_empty()) {
111f22ef01cSRoman Divacky     P->eraseFromParent();
11291bc56edSDimitry Andric     return nullptr;
113f22ef01cSRoman Divacky   }
114f22ef01cSRoman Divacky 
1157a7e6055SDimitry Andric   const DataLayout &DL = P->getModule()->getDataLayout();
1167a7e6055SDimitry Andric 
117f22ef01cSRoman Divacky   // Create a stack slot to hold the value.
118f22ef01cSRoman Divacky   AllocaInst *Slot;
119f22ef01cSRoman Divacky   if (AllocaPoint) {
1207a7e6055SDimitry Andric     Slot = new AllocaInst(P->getType(), DL.getAllocaAddrSpace(), nullptr,
121f22ef01cSRoman Divacky                           P->getName()+".reg2mem", AllocaPoint);
122f22ef01cSRoman Divacky   } else {
123f22ef01cSRoman Divacky     Function *F = P->getParent()->getParent();
1247a7e6055SDimitry Andric     Slot = new AllocaInst(P->getType(), DL.getAllocaAddrSpace(), nullptr,
1257a7e6055SDimitry Andric                           P->getName() + ".reg2mem",
1267d523365SDimitry Andric                           &F->getEntryBlock().front());
127f22ef01cSRoman Divacky   }
128f22ef01cSRoman Divacky 
129dff0c46cSDimitry Andric   // Iterate over each operand inserting a store in each predecessor.
130f22ef01cSRoman Divacky   for (unsigned i = 0, e = P->getNumIncomingValues(); i < e; ++i) {
131f22ef01cSRoman Divacky     if (InvokeInst *II = dyn_cast<InvokeInst>(P->getIncomingValue(i))) {
132f22ef01cSRoman Divacky       assert(II->getParent() != P->getIncomingBlock(i) &&
1332754fe60SDimitry Andric              "Invoke edge not supported yet"); (void)II;
134f22ef01cSRoman Divacky     }
135f22ef01cSRoman Divacky     new StoreInst(P->getIncomingValue(i), Slot,
136f22ef01cSRoman Divacky                   P->getIncomingBlock(i)->getTerminator());
137f22ef01cSRoman Divacky   }
138f22ef01cSRoman Divacky 
139dff0c46cSDimitry Andric   // Insert a load in place of the PHI and replace all uses.
1407d523365SDimitry Andric   BasicBlock::iterator InsertPt = P->getIterator();
141139f7f9bSDimitry Andric 
1427d523365SDimitry Andric   for (; isa<PHINode>(InsertPt) || InsertPt->isEHPad(); ++InsertPt)
143139f7f9bSDimitry Andric     /* empty */;   // Don't insert before PHI nodes or landingpad instrs.
144139f7f9bSDimitry Andric 
1457d523365SDimitry Andric   Value *V = new LoadInst(Slot, P->getName() + ".reload", &*InsertPt);
146f22ef01cSRoman Divacky   P->replaceAllUsesWith(V);
147f22ef01cSRoman Divacky 
148dff0c46cSDimitry Andric   // Delete PHI.
149f22ef01cSRoman Divacky   P->eraseFromParent();
150f22ef01cSRoman Divacky   return Slot;
151f22ef01cSRoman Divacky }
152