blob: c1c4759eb98cebb282e8bc8b67c909e5811bf340 [file] [log] [blame]
Chris Lattnered7b41e2003-05-27 15:45:27 +00001//===- ScalarReplAggregates.cpp - Scalar Replacement of Aggregates --------===//
John Criswellb576c942003-10-20 19:43:21 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Chris Lattnered7b41e2003-05-27 15:45:27 +00009//
10// This transformation implements the well known scalar replacement of
11// aggregates transformation. This xform breaks up alloca instructions of
12// aggregate type (structure or array) into individual alloca instructions for
Chris Lattner38aec322003-09-11 16:45:55 +000013// each member (if possible). Then, if possible, it transforms the individual
14// alloca instructions into nice clean scalar SSA form.
15//
16// This combines a simple SRoA algorithm with the Mem2Reg algorithm because
17// often interact, especially for C++ programs. As such, iterating between
18// SRoA, then Mem2Reg until we run out of things to promote works well.
Chris Lattnered7b41e2003-05-27 15:45:27 +000019//
20//===----------------------------------------------------------------------===//
21
22#include "llvm/Transforms/Scalar.h"
Chris Lattner38aec322003-09-11 16:45:55 +000023#include "llvm/Constants.h"
24#include "llvm/DerivedTypes.h"
Chris Lattnered7b41e2003-05-27 15:45:27 +000025#include "llvm/Function.h"
26#include "llvm/Pass.h"
27#include "llvm/iMemory.h"
Chris Lattner38aec322003-09-11 16:45:55 +000028#include "llvm/Analysis/Dominators.h"
Chris Lattnerbe883a22003-11-25 21:09:18 +000029#include "llvm/Support/GetElementPtrTypeIterator.h"
Chris Lattner38aec322003-09-11 16:45:55 +000030#include "llvm/Target/TargetData.h"
31#include "llvm/Transforms/Utils/PromoteMemToReg.h"
Chris Lattner6806f562003-08-01 22:15:03 +000032#include "Support/Debug.h"
Chris Lattnered7b41e2003-05-27 15:45:27 +000033#include "Support/Statistic.h"
Chris Lattner6806f562003-08-01 22:15:03 +000034#include "Support/StringExtras.h"
Chris Lattnerd8664732003-12-02 17:43:55 +000035using namespace llvm;
Brian Gaeked0fde302003-11-11 22:41:34 +000036
Chris Lattnered7b41e2003-05-27 15:45:27 +000037namespace {
Misha Brukman3cfb6b12003-09-11 16:58:31 +000038 Statistic<> NumReplaced("scalarrepl", "Number of allocas broken up");
39 Statistic<> NumPromoted("scalarrepl", "Number of allocas promoted");
Chris Lattnered7b41e2003-05-27 15:45:27 +000040
41 struct SROA : public FunctionPass {
42 bool runOnFunction(Function &F);
43
Chris Lattner38aec322003-09-11 16:45:55 +000044 bool performScalarRepl(Function &F);
45 bool performPromotion(Function &F);
46
Chris Lattnera15854c2003-08-31 00:45:13 +000047 // getAnalysisUsage - This pass does not require any passes, but we know it
48 // will not alter the CFG, so say so.
49 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
Chris Lattner43f820d2003-10-05 21:20:13 +000050 AU.addRequired<DominatorTree>();
Chris Lattner38aec322003-09-11 16:45:55 +000051 AU.addRequired<DominanceFrontier>();
52 AU.addRequired<TargetData>();
Chris Lattnera15854c2003-08-31 00:45:13 +000053 AU.setPreservesCFG();
54 }
55
Chris Lattnered7b41e2003-05-27 15:45:27 +000056 private:
Chris Lattnerb37923f2003-05-30 19:22:14 +000057 bool isSafeElementUse(Value *Ptr);
Chris Lattner5e062a12003-05-30 04:15:41 +000058 bool isSafeUseOfAllocation(Instruction *User);
Chris Lattner546fc402003-10-29 17:55:44 +000059 bool isSafeAllocaToPromote(AllocationInst *AI);
Chris Lattnered7b41e2003-05-27 15:45:27 +000060 AllocaInst *AddNewAlloca(Function &F, const Type *Ty, AllocationInst *Base);
61 };
62
63 RegisterOpt<SROA> X("scalarrepl", "Scalar Replacement of Aggregates");
64}
65
Brian Gaeked0fde302003-11-11 22:41:34 +000066// Public interface to the ScalarReplAggregates pass
Chris Lattnerd8664732003-12-02 17:43:55 +000067Pass *llvm::createScalarReplAggregatesPass() { return new SROA(); }
Chris Lattnered7b41e2003-05-27 15:45:27 +000068
69
Chris Lattnered7b41e2003-05-27 15:45:27 +000070bool SROA::runOnFunction(Function &F) {
Chris Lattnerfe7ea0d2003-09-12 15:36:03 +000071 bool Changed = performPromotion(F);
72 while (1) {
73 bool LocalChange = performScalarRepl(F);
74 if (!LocalChange) break; // No need to repromote if no scalarrepl
75 Changed = true;
76 LocalChange = performPromotion(F);
77 if (!LocalChange) break; // No need to re-scalarrepl if no promotion
78 }
Chris Lattner38aec322003-09-11 16:45:55 +000079
80 return Changed;
81}
82
83
84bool SROA::performPromotion(Function &F) {
85 std::vector<AllocaInst*> Allocas;
86 const TargetData &TD = getAnalysis<TargetData>();
Chris Lattner43f820d2003-10-05 21:20:13 +000087 DominatorTree &DT = getAnalysis<DominatorTree>();
88 DominanceFrontier &DF = getAnalysis<DominanceFrontier>();
Chris Lattner38aec322003-09-11 16:45:55 +000089
Chris Lattner02a3be02003-09-20 14:39:18 +000090 BasicBlock &BB = F.getEntryBlock(); // Get the entry node for the function
Chris Lattner38aec322003-09-11 16:45:55 +000091
Chris Lattnerfe7ea0d2003-09-12 15:36:03 +000092 bool Changed = false;
Chris Lattner38aec322003-09-11 16:45:55 +000093
94 while (1) {
95 Allocas.clear();
96
97 // Find allocas that are safe to promote, by looking at all instructions in
98 // the entry node
99 for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I)
100 if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) // Is it an alloca?
101 if (isAllocaPromotable(AI, TD))
102 Allocas.push_back(AI);
103
104 if (Allocas.empty()) break;
105
Chris Lattner43f820d2003-10-05 21:20:13 +0000106 PromoteMemToReg(Allocas, DT, DF, TD);
Chris Lattner38aec322003-09-11 16:45:55 +0000107 NumPromoted += Allocas.size();
108 Changed = true;
109 }
110
111 return Changed;
112}
113
114
115// performScalarRepl - This algorithm is a simple worklist driven algorithm,
116// which runs on all of the malloc/alloca instructions in the function, removing
117// them if they are only used by getelementptr instructions.
118//
119bool SROA::performScalarRepl(Function &F) {
Chris Lattnered7b41e2003-05-27 15:45:27 +0000120 std::vector<AllocationInst*> WorkList;
121
122 // Scan the entry basic block, adding any alloca's and mallocs to the worklist
Chris Lattner02a3be02003-09-20 14:39:18 +0000123 BasicBlock &BB = F.getEntryBlock();
Chris Lattnered7b41e2003-05-27 15:45:27 +0000124 for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I)
125 if (AllocationInst *A = dyn_cast<AllocationInst>(I))
126 WorkList.push_back(A);
127
128 // Process the worklist
129 bool Changed = false;
130 while (!WorkList.empty()) {
131 AllocationInst *AI = WorkList.back();
132 WorkList.pop_back();
133
134 // We cannot transform the allocation instruction if it is an array
Chris Lattnerd10376b2003-05-27 16:09:27 +0000135 // allocation (allocations OF arrays are ok though), and an allocation of a
136 // scalar value cannot be decomposed at all.
137 //
Chris Lattnered7b41e2003-05-27 15:45:27 +0000138 if (AI->isArrayAllocation() ||
Chris Lattnerd10376b2003-05-27 16:09:27 +0000139 (!isa<StructType>(AI->getAllocatedType()) &&
140 !isa<ArrayType>(AI->getAllocatedType()))) continue;
141
Chris Lattner5e062a12003-05-30 04:15:41 +0000142 // Check that all of the users of the allocation are capable of being
143 // transformed.
Chris Lattner546fc402003-10-29 17:55:44 +0000144 if (!isSafeAllocaToPromote(AI))
Chris Lattner5e062a12003-05-30 04:15:41 +0000145 continue;
Chris Lattnered7b41e2003-05-27 15:45:27 +0000146
147 DEBUG(std::cerr << "Found inst to xform: " << *AI);
148 Changed = true;
149
150 std::vector<AllocaInst*> ElementAllocas;
151 if (const StructType *ST = dyn_cast<StructType>(AI->getAllocatedType())) {
152 ElementAllocas.reserve(ST->getNumContainedTypes());
153 for (unsigned i = 0, e = ST->getNumContainedTypes(); i != e; ++i) {
154 AllocaInst *NA = new AllocaInst(ST->getContainedType(i), 0,
155 AI->getName() + "." + utostr(i), AI);
156 ElementAllocas.push_back(NA);
157 WorkList.push_back(NA); // Add to worklist for recursive processing
158 }
159 } else {
Chris Lattner5e062a12003-05-30 04:15:41 +0000160 const ArrayType *AT = cast<ArrayType>(AI->getAllocatedType());
Chris Lattnered7b41e2003-05-27 15:45:27 +0000161 ElementAllocas.reserve(AT->getNumElements());
162 const Type *ElTy = AT->getElementType();
163 for (unsigned i = 0, e = AT->getNumElements(); i != e; ++i) {
164 AllocaInst *NA = new AllocaInst(ElTy, 0,
165 AI->getName() + "." + utostr(i), AI);
166 ElementAllocas.push_back(NA);
167 WorkList.push_back(NA); // Add to worklist for recursive processing
168 }
169 }
170
171 // Now that we have created the alloca instructions that we want to use,
172 // expand the getelementptr instructions to use them.
173 //
174 for (Value::use_iterator I = AI->use_begin(), E = AI->use_end();
175 I != E; ++I) {
176 Instruction *User = cast<Instruction>(*I);
177 if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(User)) {
178 // We now know that the GEP is of the form: GEP <ptr>, 0, <cst>
Chris Lattnerc07736a2003-07-23 15:22:26 +0000179 uint64_t Idx = cast<ConstantInt>(GEPI->getOperand(2))->getRawValue();
Chris Lattnered7b41e2003-05-27 15:45:27 +0000180
181 assert(Idx < ElementAllocas.size() && "Index out of range?");
182 AllocaInst *AllocaToUse = ElementAllocas[Idx];
183
184 Value *RepValue;
185 if (GEPI->getNumOperands() == 3) {
186 // Do not insert a new getelementptr instruction with zero indices,
187 // only to have it optimized out later.
188 RepValue = AllocaToUse;
189 } else {
190 // We are indexing deeply into the structure, so we still need a
191 // getelement ptr instruction to finish the indexing. This may be
192 // expanded itself once the worklist is rerun.
193 //
194 std::string OldName = GEPI->getName(); // Steal the old name...
Chris Lattner261d6862003-05-30 05:26:30 +0000195 std::vector<Value*> NewArgs;
196 NewArgs.push_back(Constant::getNullValue(Type::LongTy));
197 NewArgs.insert(NewArgs.end(), GEPI->op_begin()+3, GEPI->op_end());
Chris Lattnered7b41e2003-05-27 15:45:27 +0000198 GEPI->setName("");
199 RepValue =
Chris Lattner261d6862003-05-30 05:26:30 +0000200 new GetElementPtrInst(AllocaToUse, NewArgs, OldName, GEPI);
Chris Lattnered7b41e2003-05-27 15:45:27 +0000201 }
202
203 // Move all of the users over to the new GEP.
204 GEPI->replaceAllUsesWith(RepValue);
205 // Delete the old GEP
206 GEPI->getParent()->getInstList().erase(GEPI);
207 } else {
208 assert(0 && "Unexpected instruction type!");
209 }
210 }
211
212 // Finally, delete the Alloca instruction
213 AI->getParent()->getInstList().erase(AI);
Chris Lattnerd10376b2003-05-27 16:09:27 +0000214 NumReplaced++;
Chris Lattnered7b41e2003-05-27 15:45:27 +0000215 }
216
217 return Changed;
218}
Chris Lattner5e062a12003-05-30 04:15:41 +0000219
220
221/// isSafeUseOfAllocation - Check to see if this user is an allowed use for an
222/// aggregate allocation.
223///
224bool SROA::isSafeUseOfAllocation(Instruction *User) {
Chris Lattnerbe883a22003-11-25 21:09:18 +0000225 if (!isa<GetElementPtrInst>(User)) return false;
226
227 GetElementPtrInst *GEPI = cast<GetElementPtrInst>(User);
228 gep_type_iterator I = gep_type_begin(GEPI), E = gep_type_end(GEPI);
229
230 // The GEP is safe to transform if it is of the form GEP <ptr>, 0, <cst>
231 if (I == E ||
232 I.getOperand() != Constant::getNullValue(I.getOperand()->getType()))
233 return false;
234
235 ++I;
Chris Lattnerd8664732003-12-02 17:43:55 +0000236 if (I == E || !isa<ConstantInt>(I.getOperand()))
Chris Lattnerbe883a22003-11-25 21:09:18 +0000237 return false;
238
239 // If this is a use of an array allocation, do a bit more checking for sanity.
240 if (const ArrayType *AT = dyn_cast<ArrayType>(*I)) {
241 uint64_t NumElements = AT->getNumElements();
242
243 // Check to make sure that index falls within the array. If not,
244 // something funny is going on, so we won't do the optimization.
245 //
246 if (cast<ConstantInt>(GEPI->getOperand(2))->getRawValue() >= NumElements)
Chris Lattner5e062a12003-05-30 04:15:41 +0000247 return false;
Chris Lattner5e062a12003-05-30 04:15:41 +0000248 }
Chris Lattnerbe883a22003-11-25 21:09:18 +0000249
250 // If there are any non-simple uses of this getelementptr, make sure to reject
251 // them.
252 return isSafeElementUse(GEPI);
Chris Lattner5e062a12003-05-30 04:15:41 +0000253}
254
Chris Lattnerb37923f2003-05-30 19:22:14 +0000255/// isSafeElementUse - Check to see if this use is an allowed use for a
Chris Lattner5e062a12003-05-30 04:15:41 +0000256/// getelementptr instruction of an array aggregate allocation.
257///
Chris Lattnerb37923f2003-05-30 19:22:14 +0000258bool SROA::isSafeElementUse(Value *Ptr) {
Chris Lattner5e062a12003-05-30 04:15:41 +0000259 for (Value::use_iterator I = Ptr->use_begin(), E = Ptr->use_end();
260 I != E; ++I) {
261 Instruction *User = cast<Instruction>(*I);
262 switch (User->getOpcode()) {
Chris Lattner8fce16e2003-09-12 16:02:12 +0000263 case Instruction::Load: break;
264 case Instruction::Store:
265 // Store is ok if storing INTO the pointer, not storing the pointer
266 if (User->getOperand(0) == Ptr) return false;
267 break;
Chris Lattner5e062a12003-05-30 04:15:41 +0000268 case Instruction::GetElementPtr: {
269 GetElementPtrInst *GEP = cast<GetElementPtrInst>(User);
270 if (GEP->getNumOperands() > 1) {
271 if (!isa<Constant>(GEP->getOperand(1)) ||
272 !cast<Constant>(GEP->getOperand(1))->isNullValue())
273 return false; // Using pointer arithmetic to navigate the array...
Chris Lattner5e062a12003-05-30 04:15:41 +0000274 }
Chris Lattner8fce16e2003-09-12 16:02:12 +0000275 if (!isSafeElementUse(GEP)) return false;
276 break;
Chris Lattner5e062a12003-05-30 04:15:41 +0000277 }
278 default:
279 DEBUG(std::cerr << " Transformation preventing inst: " << *User);
280 return false;
281 }
282 }
283 return true; // All users look ok :)
284}
285
286
287/// isSafeStructAllocaToPromote - Check to see if the specified allocation of a
288/// structure can be broken down into elements.
289///
Chris Lattner546fc402003-10-29 17:55:44 +0000290bool SROA::isSafeAllocaToPromote(AllocationInst *AI) {
Chris Lattner5e062a12003-05-30 04:15:41 +0000291 // Loop over the use list of the alloca. We can only transform it if all of
292 // the users are safe to transform.
293 //
294 for (Value::use_iterator I = AI->use_begin(), E = AI->use_end();
Chris Lattner546fc402003-10-29 17:55:44 +0000295 I != E; ++I)
Chris Lattner5e062a12003-05-30 04:15:41 +0000296 if (!isSafeUseOfAllocation(cast<Instruction>(*I))) {
297 DEBUG(std::cerr << "Cannot transform: " << *AI << " due to user: "
298 << *I);
299 return false;
300 }
301 return true;
302}