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