Skip to content

Commit bb1a2cc

Browse files
committed
This code was both incredibly complex and incredibly broken. Fix it.
llvm-svn: 12456
1 parent 0e64dda commit bb1a2cc

File tree

1 file changed

+57
-137
lines changed

1 file changed

+57
-137
lines changed

llvm/lib/Transforms/Utils/DemoteRegToStack.cpp

Lines changed: 57 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -8,156 +8,76 @@
88
//===----------------------------------------------------------------------===//
99
//
1010
// This file provide the function DemoteRegToStack(). This function takes a
11-
// virtual register computed by an Instruction& X and replaces it with a slot in
11+
// virtual register computed by an Instruction and replaces it with a slot in
1212
// the stack frame, allocated via alloca. It returns the pointer to the
13-
// AllocaInst inserted.
13+
// AllocaInst inserted. After this function is called on an instruction, we are
14+
// guaranteed that the only user of the instruction is a store that is
15+
// immediately after it.
1416
//
1517
//===----------------------------------------------------------------------===//
1618

1719
#include "llvm/Transforms/Utils/Local.h"
1820
#include "llvm/Function.h"
19-
#include "llvm/iMemory.h"
20-
#include "llvm/iPHINode.h"
21-
#include "llvm/iTerminators.h"
22-
#include "llvm/Type.h"
23-
#include "Support/hash_set"
21+
#include "llvm/Instructions.h"
2422
using namespace llvm;
2523

26-
typedef hash_set<PHINode*> PhiSet;
27-
typedef hash_set<PHINode*>::iterator PhiSetIterator;
28-
29-
// Helper function to push a phi *and* all its operands to the worklist!
30-
// Do not push an instruction if it is already in the result set of Phis to go.
31-
static inline void PushOperandsOnWorkList(std::vector<Instruction*>& workList,
32-
PhiSet& phisToGo, PHINode* phiN) {
33-
for (User::op_iterator OI = phiN->op_begin(), OE = phiN->op_end();
34-
OI != OE; ++OI) {
35-
Instruction* opI = cast<Instruction>(OI);
36-
if (!isa<PHINode>(opI) || !phisToGo.count(cast<PHINode>(opI)))
37-
workList.push_back(opI);
38-
}
39-
}
40-
41-
static void FindPhis(Instruction& X, PhiSet& phisToGo) {
42-
std::vector<Instruction*> workList;
43-
workList.push_back(&X);
44-
45-
// Handle the case that X itself is a Phi!
46-
if (PHINode* phiX = dyn_cast<PHINode>(&X)) {
47-
phisToGo.insert(phiX);
48-
PushOperandsOnWorkList(workList, phisToGo, phiX);
49-
}
50-
51-
// Now use a worklist to find all phis reachable from X, and
52-
// (recursively) all phis reachable from operands of such phis.
53-
while (!workList.empty()) {
54-
Instruction *I = workList.back();
55-
workList.pop_back();
56-
for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI!=E; ++UI)
57-
if (PHINode* phiN = dyn_cast<PHINode>(*UI))
58-
if (phisToGo.find(phiN) == phisToGo.end()) {
59-
// Seeing this phi for the first time: it must go!
60-
phisToGo.insert(phiN);
61-
workList.push_back(phiN);
62-
PushOperandsOnWorkList(workList, phisToGo, phiN);
24+
/// DemoteRegToStack - This function takes a virtual register computed by an
25+
/// Instruction and replaces it with a slot in the stack frame, allocated via
26+
/// alloca. This allows the CFG to be changed around without fear of
27+
/// invalidating the SSA information for the value. It returns the pointer to
28+
/// the alloca inserted to create a stack slot for I.
29+
///
30+
AllocaInst* llvm::DemoteRegToStack(Instruction &I) {
31+
if (I.use_empty()) return 0; // nothing to do!
32+
33+
// Create a stack slot to hold the value.
34+
Function *F = I.getParent()->getParent();
35+
AllocaInst *Slot = new AllocaInst(I.getType(), 0, I.getName(),
36+
F->getEntryBlock().begin());
37+
38+
// Change all of the users of the instruction to read from the stack slot
39+
// instead.
40+
while (!I.use_empty()) {
41+
Instruction *U = cast<Instruction>(I.use_back());
42+
if (PHINode *PN = dyn_cast<PHINode>(U)) {
43+
// If this is a PHI node, we can't insert a load of the value before the
44+
// use. Instead, insert the load in the predecessor block corresponding
45+
// to the incoming value.
46+
//
47+
// Note that if there are multiple edges from a basic block to this PHI
48+
// node that we'll insert multiple loads. Since DemoteRegToStack requires
49+
// a mem2reg pass after it (to produce reasonable code), we don't care.
50+
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
51+
if (PN->getIncomingValue(i) == &I) {
52+
// Insert the load into the predecessor block
53+
Value *V = new LoadInst(Slot, I.getName()+".reload",
54+
PN->getIncomingBlock(i)->getTerminator());
55+
PN->setIncomingValue(i, V);
6356
}
64-
}
65-
}
66-
67-
68-
// Insert loads before all uses of I, except uses in Phis
69-
// since all such Phis *must* be deleted.
70-
static void LoadBeforeUses(Instruction* def, AllocaInst* XSlot) {
71-
for (unsigned nPhis = 0; def->use_size() - nPhis > 0; ) {
72-
Instruction* useI = cast<Instruction>(def->use_back());
73-
if (!isa<PHINode>(useI)) {
74-
LoadInst* loadI =
75-
new LoadInst(XSlot, std::string("Load")+XSlot->getName(), useI);
76-
useI->replaceUsesOfWith(def, loadI);
77-
} else
78-
++nPhis;
79-
}
80-
}
81-
82-
static void AddLoadsAndStores(AllocaInst* XSlot, Instruction& X,
83-
PhiSet& phisToGo) {
84-
for (PhiSetIterator PI=phisToGo.begin(), PE=phisToGo.end(); PI != PE; ++PI) {
85-
PHINode* pn = *PI;
8657

87-
// First, insert loads before all uses except uses in Phis.
88-
// Do this first because new stores will appear as uses also!
89-
LoadBeforeUses(pn, XSlot);
90-
91-
// For every incoming operand of the Phi, insert a store either
92-
// just after the instruction defining the value or just before the
93-
// predecessor of the Phi if the value is a formal, not an instruction.
94-
//
95-
for (unsigned i=0, N=pn->getNumIncomingValues(); i < N; ++i) {
96-
Value* phiOp = pn->getIncomingValue(i);
97-
if (phiOp != &X &&
98-
(!isa<PHINode>(phiOp) || !phisToGo.count(cast<PHINode>(phiOp)))) {
99-
// This operand is not a phi that will be deleted: need to store.
100-
assert(!isa<TerminatorInst>(phiOp));
101-
102-
Instruction* storeBefore;
103-
if (Instruction* I = dyn_cast<Instruction>(phiOp)) {
104-
// phiOp is an instruction, store its result right after it.
105-
assert(I->getNext() && "Non-terminator without successor?");
106-
storeBefore = I->getNext();
107-
} else {
108-
// If not, it must be a formal: store it at the end of the
109-
// predecessor block of the Phi (*not* at function entry!).
110-
storeBefore = pn->getIncomingBlock(i)->getTerminator();
111-
}
112-
113-
// Create instr. to store the value of phiOp before `insertBefore'
114-
StoreInst* storeI = new StoreInst(phiOp, XSlot, storeBefore);
115-
}
58+
} else {
59+
// If this is a normal instruction, just insert a load.
60+
Value *V = new LoadInst(Slot, I.getName()+".reload", U);
61+
U->replaceUsesOfWith(&I, V);
11662
}
11763
}
118-
}
11964

120-
//----------------------------------------------------------------------------
121-
// function DemoteRegToStack()
122-
//
123-
// This function takes a virtual register computed by an
124-
// Instruction& X and replaces it with a slot in the stack frame,
125-
// allocated via alloca. It has to:
126-
// (1) Identify all Phi operations that have X as an operand and
127-
// transitively other Phis that use such Phis;
128-
// (2) Store all values merged with X via Phi operations to the stack slot;
129-
// (3) Load the value from the stack slot just before any use of X or any
130-
// of the Phis that were eliminated; and
131-
// (4) Delete all the Phis, which should all now be dead.
132-
//
133-
// Returns the pointer to the alloca inserted to create a stack slot for X.
134-
//
135-
AllocaInst* llvm::DemoteRegToStack(Instruction& X) {
136-
if (X.getType() == Type::VoidTy)
137-
return 0; // nothing to do!
13865

139-
// Find all Phis involving X or recursively using such Phis or Phis
140-
// involving operands of such Phis (essentially all Phis in the "web" of X)
141-
PhiSet phisToGo;
142-
FindPhis(X, phisToGo);
143-
144-
// Create a stack slot to hold X
145-
Function* parentFunc = X.getParent()->getParent();
146-
AllocaInst *XSlot = new AllocaInst(X.getType(), 0, X.getName(),
147-
parentFunc->getEntryBlock().begin());
148-
149-
150-
// Insert loads before all uses of X and (*only then*) insert store after X
151-
assert(X.getNext() && "Non-terminator (since non-void) with no successor?");
152-
LoadBeforeUses(&X, XSlot);
153-
StoreInst* storeI = new StoreInst(&X, XSlot, X.getNext());
154-
155-
// Do the same for all the phis that will be deleted
156-
AddLoadsAndStores(XSlot, X, phisToGo);
157-
158-
// Delete the phis and return the alloca instruction
159-
for (PhiSetIterator PI = phisToGo.begin(), E = phisToGo.end(); PI != E; ++PI)
160-
(*PI)->getParent()->getInstList().erase(*PI);
66+
// Insert stores of the computed value into the stack slot. We have to be
67+
// careful is I is an invoke instruction though, because we can't insert the
68+
// store AFTER the terminator instruction.
69+
if (!isa<TerminatorInst>(I)) {
70+
BasicBlock::iterator InsertPt = &I;
71+
for (++InsertPt; isa<PHINode>(InsertPt); ++InsertPt)
72+
/* empty */; // Don't insert before any PHI nodes.
73+
new StoreInst(&I, Slot, InsertPt);
74+
} else {
75+
// FIXME: We cannot yet demote invoke instructions to the stack, because
76+
// doing so would require breaking critical edges. This should be fixed
77+
// eventually.
78+
assert(0 &&
79+
"Cannot demote the value computed by an invoke instruction yet!");
80+
}
16181

162-
return XSlot;
82+
return Slot;
16383
}

0 commit comments

Comments
 (0)