Mercurial > projects > ldc
annotate gen/passes/GarbageCollect2Stack.cpp @ 1491:360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
is found to see if it can actually happen instead of just assuming it will.
This allows it to catch cases like
{{{
int i;
Foo f;
while (cond(i))
f = new Foo(i++);
return f.value;
}}}
where it previously wouldn't because a phi using the allocation would appear in
the condition block to propagate it to the use after the loop.
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Thu, 11 Jun 2009 02:04:44 +0200 |
parents | ca31a8e9c42b |
children | d1652c8fb4f6 |
rev | line source |
---|---|
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
1 //===- GarbageCollect2Stack - Optimize calls to the D garbage collector ---===// |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
2 // |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
3 // The LLVM D Compiler |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
4 // |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
5 // This file is distributed under the University of Illinois Open Source |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
6 // License. See LICENSE.TXT for details. |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
7 // |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
8 //===----------------------------------------------------------------------===// |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
9 // |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
10 // This file attempts to turn allocations on the garbage-collected heap into |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
11 // stack allocations. |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
12 // |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
13 //===----------------------------------------------------------------------===// |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
14 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
15 #include "gen/metadata.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
16 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
17 // This pass doesn't work without metadata, so #ifdef it out entirely if the |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
18 // LLVM version in use doesn't support it. |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
19 #ifdef USE_METADATA |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
20 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
21 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
22 #define DEBUG_TYPE "dgc2stack" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
23 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
24 #include "Passes.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
25 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
26 #include "llvm/Pass.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
27 #include "llvm/Module.h" |
1491
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
28 #include "llvm/Constants.h" |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
29 #include "llvm/Intrinsics.h" |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
30 #include "llvm/Support/CallSite.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
31 #include "llvm/Support/CommandLine.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
32 #include "llvm/Support/IRBuilder.h" |
1424
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
33 #include "llvm/Analysis/CallGraph.h" |
1486
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
34 #include "llvm/Analysis/Dominators.h" |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
35 #include "llvm/Analysis/ValueTracking.h" |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
36 #include "llvm/Target/TargetData.h" |
1486
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
37 #include "llvm/ADT/SmallSet.h" |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
38 #include "llvm/ADT/SmallVector.h" |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
39 #include "llvm/ADT/StringMap.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
40 #include "llvm/ADT/Statistic.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
41 #include "llvm/Support/Compiler.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
42 #include "llvm/Support/Debug.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
43 using namespace llvm; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
44 |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
45 STATISTIC(NumGcToStack, "Number of calls promoted to constant-size allocas"); |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
46 STATISTIC(NumToDynSize, "Number of calls promoted to dynamically-sized allocas"); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
47 STATISTIC(NumDeleted, "Number of GC calls deleted because the return value was unused"); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
48 |
1424
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
49 |
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
50 namespace { |
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
51 struct Analysis { |
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
52 TargetData& TD; |
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
53 const Module& M; |
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
54 CallGraph* CG; |
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
55 CallGraphNode* CGNode; |
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
56 |
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
57 const Type* getTypeFor(Value* typeinfo) const; |
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
58 }; |
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
59 } |
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
60 |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
61 //===----------------------------------------------------------------------===// |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
62 // Helper functions |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
63 //===----------------------------------------------------------------------===// |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
64 |
1424
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
65 void EmitMemSet(IRBuilder<>& B, Value* Dst, Value* Val, Value* Len, |
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
66 const Analysis& A) { |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
67 Dst = B.CreateBitCast(Dst, PointerType::getUnqual(Type::Int8Ty)); |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
68 |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
69 Module *M = B.GetInsertBlock()->getParent()->getParent(); |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
70 const Type* Tys[1]; |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
71 Tys[0] = Len->getType(); |
1424
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
72 Function *MemSet = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys, 1); |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
73 Value *Align = ConstantInt::get(Type::Int32Ty, 1); |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
74 |
1424
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
75 CallSite CS = B.CreateCall4(MemSet, Dst, Val, Len, Align); |
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
76 if (A.CGNode) |
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
77 A.CGNode->addCalledFunction(CS, A.CG->getOrInsertFunction(MemSet)); |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
78 } |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
79 |
1424
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
80 static void EmitMemZero(IRBuilder<>& B, Value* Dst, Value* Len, |
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
81 const Analysis& A) { |
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
82 EmitMemSet(B, Dst, ConstantInt::get(Type::Int8Ty, 0), Len, A); |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
83 } |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
84 |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
85 |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
86 //===----------------------------------------------------------------------===// |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
87 // Helpers for specific types of GC calls. |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
88 //===----------------------------------------------------------------------===// |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
89 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
90 namespace { |
1306 | 91 class FunctionInfo { |
92 protected: | |
93 const Type* Ty; | |
94 | |
95 public: | |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
96 unsigned TypeInfoArgNr; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
97 bool SafeToDelete; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
98 |
1306 | 99 // Analyze the current call, filling in some fields. Returns true if |
100 // this is an allocation we can stack-allocate. | |
101 virtual bool analyze(CallSite CS, const Analysis& A) { | |
102 Value* TypeInfo = CS.getArgument(TypeInfoArgNr); | |
103 Ty = A.getTypeFor(TypeInfo); | |
104 return (Ty != NULL); | |
105 } | |
106 | |
107 // Returns the alloca to replace this call. | |
108 // It will always be inserted before the call. | |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
109 virtual AllocaInst* promote(CallSite CS, IRBuilder<>& B, const Analysis& A) { |
1306 | 110 NumGcToStack++; |
111 | |
112 Instruction* Begin = CS.getCaller()->getEntryBlock().begin(); | |
1350
15e9762bb620
Adds explicit alignment information for alloca instructions in general, there's a few cases that still needs to be looked at but this should catch the majority. Fixes ticket #293 .
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1344
diff
changeset
|
113 return new AllocaInst(Ty, ".nongc_mem", Begin); // FIXME: align? |
1306 | 114 } |
115 | |
116 FunctionInfo(unsigned typeInfoArgNr, bool safeToDelete) | |
117 : TypeInfoArgNr(typeInfoArgNr), SafeToDelete(safeToDelete) {} | |
118 }; | |
119 | |
120 class ArrayFI : public FunctionInfo { | |
121 Value* arrSize; | |
122 int ArrSizeArgNr; | |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
123 bool Initialized; |
1306 | 124 |
125 public: | |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
126 ArrayFI(unsigned tiArgNr, bool safeToDelete, bool initialized, |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
127 unsigned arrSizeArgNr) |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
128 : FunctionInfo(tiArgNr, safeToDelete), |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
129 ArrSizeArgNr(arrSizeArgNr), |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
130 Initialized(initialized) |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
131 {} |
1306 | 132 |
133 virtual bool analyze(CallSite CS, const Analysis& A) { | |
134 if (!FunctionInfo::analyze(CS, A)) | |
135 return false; | |
136 | |
137 arrSize = CS.getArgument(ArrSizeArgNr); | |
138 const IntegerType* SizeType = | |
139 dyn_cast<IntegerType>(arrSize->getType()); | |
140 if (!SizeType) | |
141 return false; | |
142 unsigned bits = SizeType->getBitWidth(); | |
143 if (bits > 32) { | |
144 // The array size of an alloca must be an i32, so make sure | |
145 // the conversion is safe. | |
146 APInt Mask = APInt::getHighBitsSet(bits, bits - 32); | |
147 APInt KnownZero(bits, 0), KnownOne(bits, 0); | |
148 ComputeMaskedBits(arrSize, Mask, KnownZero, KnownOne, &A.TD); | |
149 if ((KnownZero & Mask) != Mask) | |
150 return false; | |
151 } | |
152 // Extract the element type from the array type. | |
153 const StructType* ArrTy = dyn_cast<StructType>(Ty); | |
154 assert(ArrTy && "Dynamic array type not a struct?"); | |
155 assert(isa<IntegerType>(ArrTy->getElementType(0))); | |
156 const PointerType* PtrTy = | |
157 cast<PointerType>(ArrTy->getElementType(1)); | |
158 Ty = PtrTy->getElementType(); | |
159 return true; | |
160 } | |
161 | |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
162 virtual AllocaInst* promote(CallSite CS, IRBuilder<>& B, const Analysis& A) { |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
163 IRBuilder<> Builder = B; |
1306 | 164 // If the allocation is of constant size it's best to put it in the |
165 // entry block, so do so if we're not already there. | |
166 // For dynamically-sized allocations it's best to avoid the overhead | |
167 // of allocating them if possible, so leave those where they are. | |
168 // While we're at it, update statistics too. | |
169 if (isa<Constant>(arrSize)) { | |
170 BasicBlock& Entry = CS.getCaller()->getEntryBlock(); | |
171 if (Builder.GetInsertBlock() != &Entry) | |
172 Builder.SetInsertPoint(&Entry, Entry.begin()); | |
173 NumGcToStack++; | |
174 } else { | |
175 NumToDynSize++; | |
176 } | |
177 | |
178 // Convert array size to 32 bits if necessary | |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
179 Value* count = Builder.CreateIntCast(arrSize, Type::Int32Ty, false); |
1350
15e9762bb620
Adds explicit alignment information for alloca instructions in general, there's a few cases that still needs to be looked at but this should catch the majority. Fixes ticket #293 .
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1344
diff
changeset
|
180 AllocaInst* alloca = Builder.CreateAlloca(Ty, count, ".nongc_mem"); // FIXME: align? |
1306 | 181 |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
182 if (Initialized) { |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
183 // For now, only zero-init is supported. |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
184 uint64_t size = A.TD.getTypeStoreSize(Ty); |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
185 Value* TypeSize = ConstantInt::get(arrSize->getType(), size); |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
186 // Use the original B to put initialization at the |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
187 // allocation site. |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
188 Value* Size = B.CreateMul(TypeSize, arrSize); |
1424
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
189 EmitMemZero(B, alloca, Size, A); |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
190 } |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
191 |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
192 return alloca; |
1306 | 193 } |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
194 }; |
1317
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
195 |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
196 // FunctionInfo for _d_allocclass |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
197 class AllocClassFI : public FunctionInfo { |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
198 public: |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
199 virtual bool analyze(CallSite CS, const Analysis& A) { |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
200 // This call contains no TypeInfo parameter, so don't call the |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
201 // base class implementation here... |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
202 if (CS.arg_size() != 1) |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
203 return false; |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
204 Value* arg = CS.getArgument(0)->stripPointerCasts(); |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
205 GlobalVariable* ClassInfo = dyn_cast<GlobalVariable>(arg); |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
206 if (!ClassInfo) |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
207 return false; |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
208 |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
209 std::string metaname = CD_PREFIX; |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
210 metaname.append(ClassInfo->getNameStart(), ClassInfo->getNameEnd()); |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
211 |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
212 GlobalVariable* global = A.M.getGlobalVariable(metaname); |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
213 if (!global || !global->hasInitializer()) |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
214 return false; |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
215 |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
216 MDNode* node = dyn_cast<MDNode>(global->getInitializer()); |
1343
c21a6654cce2
Update for metadata changes in LLVM trunk.
Frits van Bommel <fvbommel wxs.nl>
parents:
1317
diff
changeset
|
217 if (!node || MD_GetNumElements(node) != CD_NumFields) |
1317
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
218 return false; |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
219 |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
220 // Inserting destructor calls is not implemented yet, so classes |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
221 // with destructors are ignored for now. |
1343
c21a6654cce2
Update for metadata changes in LLVM trunk.
Frits van Bommel <fvbommel wxs.nl>
parents:
1317
diff
changeset
|
222 Constant* hasDestructor = dyn_cast<Constant>(MD_GetElement(node, CD_Finalize)); |
1317
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
223 // We can't stack-allocate if the class has a custom deallocator |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
224 // (Custom allocators don't get turned into this runtime call, so |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
225 // those can be ignored) |
1343
c21a6654cce2
Update for metadata changes in LLVM trunk.
Frits van Bommel <fvbommel wxs.nl>
parents:
1317
diff
changeset
|
226 Constant* hasCustomDelete = dyn_cast<Constant>(MD_GetElement(node, CD_CustomDelete)); |
1317
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
227 if (hasDestructor == NULL || hasCustomDelete == NULL) |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
228 return false; |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
229 |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
230 if (ConstantExpr::getOr(hasDestructor, hasCustomDelete) |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
231 != ConstantInt::getFalse()) |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
232 return false; |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
233 |
1343
c21a6654cce2
Update for metadata changes in LLVM trunk.
Frits van Bommel <fvbommel wxs.nl>
parents:
1317
diff
changeset
|
234 Ty = MD_GetElement(node, CD_BodyType)->getType(); |
1317
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
235 return true; |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
236 } |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
237 |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
238 // The default promote() should be fine. |
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
239 |
1361
67ac63740c7f
silence a gcc warning
Benjamin Kramer <benny.kra@gmail.com>
parents:
1350
diff
changeset
|
240 AllocClassFI() : FunctionInfo(~0u, true) {} |
1317
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
241 }; |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
242 } |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
243 |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
244 |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
245 //===----------------------------------------------------------------------===// |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
246 // GarbageCollect2Stack Pass Implementation |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
247 //===----------------------------------------------------------------------===// |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
248 |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
249 namespace { |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
250 /// This pass replaces GC calls with alloca's |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
251 /// |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
252 class VISIBILITY_HIDDEN GarbageCollect2Stack : public FunctionPass { |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
253 StringMap<FunctionInfo*> KnownFunctions; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
254 Module* M; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
255 |
1306 | 256 FunctionInfo AllocMemoryT; |
257 ArrayFI NewArrayVT; | |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
258 ArrayFI NewArrayT; |
1317
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
259 AllocClassFI AllocClass; |
1306 | 260 |
261 public: | |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
262 static char ID; // Pass identification |
1306 | 263 GarbageCollect2Stack(); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
264 |
1306 | 265 bool doInitialization(Module &M) { |
266 this->M = &M; | |
1438
c363d131c1ef
Add some missing returns.
Frits van Bommel <fvbommel wxs.nl>
parents:
1424
diff
changeset
|
267 return false; |
1306 | 268 } |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
269 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
270 bool runOnFunction(Function &F); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
271 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
272 virtual void getAnalysisUsage(AnalysisUsage &AU) const { |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
273 AU.addRequired<TargetData>(); |
1486
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
274 AU.addRequired<DominatorTree>(); |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
275 |
1424
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
276 AU.addPreserved<CallGraph>(); |
1486
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
277 AU.addPreserved<DominatorTree>(); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
278 } |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
279 }; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
280 char GarbageCollect2Stack::ID = 0; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
281 } // end anonymous namespace. |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
282 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
283 static RegisterPass<GarbageCollect2Stack> |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
284 X("dgc2stack", "Promote (GC'ed) heap allocations to stack"); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
285 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
286 // Public interface to the pass. |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
287 FunctionPass *createGarbageCollect2Stack() { |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
288 return new GarbageCollect2Stack(); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
289 } |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
290 |
1306 | 291 GarbageCollect2Stack::GarbageCollect2Stack() |
292 : FunctionPass(&ID), | |
293 AllocMemoryT(0, true), | |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
294 NewArrayVT(0, true, false, 1), |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
295 NewArrayT(0, true, true, 1) |
1306 | 296 { |
297 KnownFunctions["_d_allocmemoryT"] = &AllocMemoryT; | |
298 KnownFunctions["_d_newarrayvT"] = &NewArrayVT; | |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
299 KnownFunctions["_d_newarrayT"] = &NewArrayT; |
1317
4099548c80e0
Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents:
1316
diff
changeset
|
300 KnownFunctions["_d_allocclass"] = &AllocClass; |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
301 } |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
302 |
1424
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
303 static void RemoveCall(CallSite CS, const Analysis& A) { |
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
304 if (CS.isInvoke()) { |
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
305 InvokeInst* Invoke = cast<InvokeInst>(CS.getInstruction()); |
1298
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
306 // If this was an invoke instruction, we need to do some extra |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
307 // work to preserve the control flow. |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
308 |
1491
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
309 // Create a "conditional" branch that -simplifycfg can clean up, so we |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
310 // can keep using the DominatorTree without updating it. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
311 BranchInst::Create(Invoke->getNormalDest(), Invoke->getUnwindDest(), |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
312 ConstantInt::getTrue(), Invoke->getParent()); |
1298
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
313 } |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
314 // Remove the runtime call. |
1424
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
315 if (A.CGNode) |
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
316 A.CGNode->removeCallEdgeFor(CS); |
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
317 CS.getInstruction()->eraseFromParent(); |
1298
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
318 } |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
319 |
1488
ca31a8e9c42b
Oops, I accidentally pushed r1486 before the last touches were committed.
Frits van Bommel <fvbommel wxs.nl>
parents:
1486
diff
changeset
|
320 static bool isSafeToStackAllocate(Instruction* Alloc, DominatorTree& DT); |
ca31a8e9c42b
Oops, I accidentally pushed r1486 before the last touches were committed.
Frits van Bommel <fvbommel wxs.nl>
parents:
1486
diff
changeset
|
321 |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
322 /// runOnFunction - Top level algorithm. |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
323 /// |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
324 bool GarbageCollect2Stack::runOnFunction(Function &F) { |
1491
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
325 DEBUG(DOUT << "\nRunning -dgc2stack on function " << F.getName() << '\n'); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
326 |
1486
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
327 TargetData& TD = getAnalysis<TargetData>(); |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
328 DominatorTree& DT = getAnalysis<DominatorTree>(); |
1424
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
329 CallGraph* CG = getAnalysisIfAvailable<CallGraph>(); |
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
330 CallGraphNode* CGNode = CG ? (*CG)[&F] : NULL; |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
331 |
1488
ca31a8e9c42b
Oops, I accidentally pushed r1486 before the last touches were committed.
Frits van Bommel <fvbommel wxs.nl>
parents:
1486
diff
changeset
|
332 Analysis A = { TD, *M, CG, CGNode }; |
1306 | 333 |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
334 BasicBlock& Entry = F.getEntryBlock(); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
335 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
336 IRBuilder<> AllocaBuilder(&Entry, Entry.begin()); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
337 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
338 bool Changed = false; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
339 for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
340 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
341 // Ignore non-calls. |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
342 Instruction* Inst = I++; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
343 CallSite CS = CallSite::get(Inst); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
344 if (!CS.getInstruction()) |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
345 continue; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
346 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
347 // Ignore indirect calls and calls to non-external functions. |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
348 Function *Callee = CS.getCalledFunction(); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
349 if (Callee == 0 || !Callee->isDeclaration() || |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
350 !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage())) |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
351 continue; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
352 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
353 // Ignore unknown calls. |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
354 const char *CalleeName = Callee->getNameStart(); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
355 StringMap<FunctionInfo*>::iterator OMI = |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
356 KnownFunctions.find(CalleeName, CalleeName+Callee->getNameLen()); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
357 if (OMI == KnownFunctions.end()) continue; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
358 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
359 assert(isa<PointerType>(Inst->getType()) |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
360 && "GC function doesn't return a pointer?"); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
361 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
362 FunctionInfo* info = OMI->getValue(); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
363 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
364 if (Inst->use_empty() && info->SafeToDelete) { |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
365 Changed = true; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
366 NumDeleted++; |
1424
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
367 RemoveCall(CS, A); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
368 continue; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
369 } |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
370 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
371 DEBUG(DOUT << "GarbageCollect2Stack inspecting: " << *Inst); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
372 |
1488
ca31a8e9c42b
Oops, I accidentally pushed r1486 before the last touches were committed.
Frits van Bommel <fvbommel wxs.nl>
parents:
1486
diff
changeset
|
373 if (!info->analyze(CS, A) || !isSafeToStackAllocate(Inst, DT)) |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
374 continue; |
1305
8215dbf0e09f
Postpone (expensive) escape analysis until we're sure it's needed.
Frits van Bommel <fvbommel wxs.nl>
parents:
1298
diff
changeset
|
375 |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
376 // Let's alloca this! |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
377 Changed = true; |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
378 |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
379 IRBuilder<> Builder(BB, Inst); |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
380 Value* newVal = info->promote(CS, Builder, A); |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
381 |
1343
c21a6654cce2
Update for metadata changes in LLVM trunk.
Frits van Bommel <fvbommel wxs.nl>
parents:
1317
diff
changeset
|
382 DEBUG(DOUT << "Promoted to: " << *newVal); |
c21a6654cce2
Update for metadata changes in LLVM trunk.
Frits van Bommel <fvbommel wxs.nl>
parents:
1317
diff
changeset
|
383 |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
384 // Make sure the type is the same as it was before, and replace all |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
385 // uses of the runtime call with the alloca. |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
386 if (newVal->getType() != Inst->getType()) |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
387 newVal = Builder.CreateBitCast(newVal, Inst->getType()); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
388 Inst->replaceAllUsesWith(newVal); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
389 |
1424
ad999630aa35
Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents:
1361
diff
changeset
|
390 RemoveCall(CS, A); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
391 } |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
392 } |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
393 |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
394 return Changed; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
395 } |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
396 |
1306 | 397 const Type* Analysis::getTypeFor(Value* typeinfo) const { |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
398 GlobalVariable* ti_global = dyn_cast<GlobalVariable>(typeinfo->stripPointerCasts()); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
399 if (!ti_global) |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
400 return NULL; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
401 |
1291
875afb7a93b6
Factor out some constants into the header so producers and consumers of
Frits van Bommel <fvbommel wxs.nl>
parents:
1285
diff
changeset
|
402 std::string metaname = TD_PREFIX; |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
403 metaname.append(ti_global->getNameStart(), ti_global->getNameEnd()); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
404 |
1306 | 405 GlobalVariable* global = M.getGlobalVariable(metaname); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
406 if (!global || !global->hasInitializer()) |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
407 return NULL; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
408 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
409 MDNode* node = dyn_cast<MDNode>(global->getInitializer()); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
410 if (!node) |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
411 return NULL; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
412 |
1344
3297edb697eb
Re-enable consistency check for fixed LLVM versions.
Frits van Bommel <fvbommel wxs.nl>
parents:
1343
diff
changeset
|
413 if (MD_GetNumElements(node) != TD_NumFields) |
3297edb697eb
Re-enable consistency check for fixed LLVM versions.
Frits van Bommel <fvbommel wxs.nl>
parents:
1343
diff
changeset
|
414 return NULL; |
3297edb697eb
Re-enable consistency check for fixed LLVM versions.
Frits van Bommel <fvbommel wxs.nl>
parents:
1343
diff
changeset
|
415 if (TD_Confirm >= 0 && (!MD_GetElement(node, TD_Confirm) || |
3297edb697eb
Re-enable consistency check for fixed LLVM versions.
Frits van Bommel <fvbommel wxs.nl>
parents:
1343
diff
changeset
|
416 MD_GetElement(node, TD_Confirm)->stripPointerCasts() != ti_global)) |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
417 return NULL; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
418 |
1343
c21a6654cce2
Update for metadata changes in LLVM trunk.
Frits van Bommel <fvbommel wxs.nl>
parents:
1317
diff
changeset
|
419 return MD_GetElement(node, TD_Type)->getType(); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
420 } |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
421 |
1491
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
422 /// Returns whether Def is used by any instruction that is reachable from Alloc |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
423 /// (without executing Def again). |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
424 static bool mayBeUsedAfterRealloc(Instruction* Def, Instruction* Alloc, DominatorTree& DT) { |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
425 DOUT << "### mayBeUsedAfterRealloc()\n" << *Def << *Alloc; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
426 |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
427 // If the definition isn't used it obviously won't be used after the |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
428 // allocation. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
429 // If it does not dominate the allocation, there's no way for it to be used |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
430 // without going through Def again first, since the definition couldn't |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
431 // dominate the user either. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
432 if (Def->use_empty() || !DT.dominates(Def, Alloc)) { |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
433 DOUT << "### No uses or does not dominate allocation\n"; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
434 return false; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
435 } |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
436 |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
437 DOUT << "### Def dominates Alloc\n"; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
438 |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
439 BasicBlock* DefBlock = Def->getParent(); |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
440 BasicBlock* AllocBlock = Alloc->getParent(); |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
441 |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
442 // Create a set of users and one of blocks containing users. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
443 SmallSet<User*, 16> Users; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
444 SmallSet<BasicBlock*, 16> UserBlocks; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
445 for (Instruction::use_iterator UI = Def->use_begin(), UE = Def->use_end(); |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
446 UI != UE; ++UI) { |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
447 Instruction* User = cast<Instruction>(*UI); |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
448 DOUT << "USER: " << *User; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
449 BasicBlock* UserBlock = User->getParent(); |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
450 |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
451 // This dominance check is not performed if they're in the same block |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
452 // because it will just walk the instruction list to figure it out. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
453 // We will instead do that ourselves in the first iteration (for all |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
454 // users at once). |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
455 if (AllocBlock != UserBlock && DT.dominates(AllocBlock, UserBlock)) { |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
456 // There's definitely a path from alloc to this user that does not |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
457 // go through Def, namely any path that ends up in that user. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
458 DOUT << "### Alloc dominates user " << *User; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
459 return true; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
460 } |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
461 |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
462 // Phi nodes are checked separately, so no need to enter them here. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
463 if (!isa<PHINode>(User)) { |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
464 Users.insert(User); |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
465 UserBlocks.insert(UserBlock); |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
466 } |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
467 } |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
468 |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
469 // Contains first instruction of block to inspect. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
470 typedef std::pair<BasicBlock*, BasicBlock::iterator> StartPoint; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
471 SmallVector<StartPoint, 16> Worklist; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
472 // Keeps track of successors that have been added to the work list. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
473 SmallSet<BasicBlock*, 16> Visited; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
474 |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
475 // Start just after the allocation. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
476 // Note that we don't insert AllocBlock into the Visited set here so the |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
477 // start of the block will get inspected if it's reachable. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
478 BasicBlock::iterator Start = Alloc; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
479 ++Start; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
480 Worklist.push_back(StartPoint(AllocBlock, Start)); |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
481 |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
482 while (!Worklist.empty()) { |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
483 StartPoint sp = Worklist.pop_back_val(); |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
484 BasicBlock* B = sp.first; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
485 BasicBlock::iterator BBI = sp.second; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
486 // BBI is either just after the allocation (in the first iteration) |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
487 // or just after the last phi node in B (in subsequent iterations) here. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
488 |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
489 // This whole 'if' is just a way to avoid performing the inner 'for' |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
490 // loop when it can be determined not to be necessary, avoiding |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
491 // potentially expensive walks of the instruction list. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
492 // It should be equivalent to just doing the loop. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
493 if (UserBlocks.count(B)) { |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
494 if (B != DefBlock && B != AllocBlock) { |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
495 // This block does not contain the definition or the allocation, |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
496 // so any user in this block is definitely reachable without |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
497 // finding either the definition or the allocation. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
498 DOUT << "### Block " << B->getName() |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
499 << " contains a reachable user\n"; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
500 return true; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
501 } |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
502 // We need to walk the instructions in the block to see whether we |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
503 // reach a user before we reach the definition or the allocation. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
504 for (BasicBlock::iterator E = B->end(); BBI != E; ++BBI) { |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
505 if (&*BBI == Alloc || &*BBI == Def) |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
506 break; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
507 if (Users.count(BBI)) { |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
508 DOUT << "### Problematic user: " << *BBI; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
509 return true; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
510 } |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
511 } |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
512 } else if (B == DefBlock || (B == AllocBlock && BBI != Start)) { |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
513 // There are no users in the block so the def or the allocation |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
514 // will be encountered before any users though this path. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
515 // Skip to the next item on the worklist. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
516 continue; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
517 } else { |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
518 // No users and no definition or allocation after the start point, |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
519 // so just keep going. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
520 } |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
521 |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
522 // All instructions after the starting point in this block have been |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
523 // accounted for. Look for successors to add to the work list. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
524 TerminatorInst* Term = B->getTerminator(); |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
525 unsigned SuccCount = Term->getNumSuccessors(); |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
526 for (unsigned i = 0; i < SuccCount; i++) { |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
527 BasicBlock* Succ = Term->getSuccessor(i); |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
528 BBI = Succ->begin(); |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
529 // Check phi nodes here because we only care about the operand |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
530 // coming in from this block. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
531 bool SeenDef = false; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
532 while (isa<PHINode>(BBI)) { |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
533 if (Def == cast<PHINode>(BBI)->getIncomingValueForBlock(B)) { |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
534 DOUT << "### Problematic phi user: " << *BBI; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
535 return true; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
536 } |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
537 SeenDef |= (Def == &*BBI); |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
538 ++BBI; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
539 } |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
540 // If none of the phis we just looked at were the definition, we |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
541 // haven't seen this block yet, and it's dominated by the def |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
542 // (meaning paths through it could lead to users), add the block and |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
543 // the first non-phi to the worklist. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
544 if (!SeenDef && Visited.insert(Succ) && DT.dominates(DefBlock, Succ)) |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
545 Worklist.push_back(StartPoint(Succ, BBI)); |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
546 } |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
547 } |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
548 // No users found in any block reachable from Alloc |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
549 // without going through the definition again. |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
550 return false; |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
551 } |
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
552 |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
553 |
1486
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
554 /// isSafeToStackAllocate - Return true if the GC call passed in is safe to turn |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
555 /// into a stack allocation. This requires that the return value does not |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
556 /// escape from the function and no derived pointers are live at the call site |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
557 /// (i.e. if it's in a loop then the function can't use any pointer returned |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
558 /// from an earlier call after a new call has been made) |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
559 /// |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
560 /// This is currently conservative where loops are involved: it can handle |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
561 /// simple loops, but returns false if any derived pointer is used in a |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
562 /// subsequent iteration. |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
563 /// |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
564 /// Based on LLVM's PointerMayBeCaptured(), which only does escape analysis but |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
565 /// doesn't care about loops. |
1488
ca31a8e9c42b
Oops, I accidentally pushed r1486 before the last touches were committed.
Frits van Bommel <fvbommel wxs.nl>
parents:
1486
diff
changeset
|
566 bool isSafeToStackAllocate(Instruction* Alloc, DominatorTree& DT) { |
ca31a8e9c42b
Oops, I accidentally pushed r1486 before the last touches were committed.
Frits van Bommel <fvbommel wxs.nl>
parents:
1486
diff
changeset
|
567 assert(isa<PointerType>(Alloc->getType()) && "Allocation is not a pointer?"); |
1486
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
568 Value* V = Alloc; |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
569 |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
570 SmallVector<Use*, 16> Worklist; |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
571 SmallSet<Use*, 16> Visited; |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
572 |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
573 for (Value::use_iterator UI = V->use_begin(), UE = V->use_end(); |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
574 UI != UE; ++UI) { |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
575 Use *U = &UI.getUse(); |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
576 Visited.insert(U); |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
577 Worklist.push_back(U); |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
578 } |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
579 |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
580 while (!Worklist.empty()) { |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
581 Use *U = Worklist.pop_back_val(); |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
582 Instruction *I = cast<Instruction>(U->getUser()); |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
583 V = U->get(); |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
584 |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
585 switch (I->getOpcode()) { |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
586 case Instruction::Call: |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
587 case Instruction::Invoke: { |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
588 CallSite CS = CallSite::get(I); |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
589 // Not captured if the callee is readonly, doesn't return a copy through |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
590 // its return value and doesn't unwind (a readonly function can leak bits |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
591 // by throwing an exception or not depending on the input value). |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
592 if (CS.onlyReadsMemory() && CS.doesNotThrow() && |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
593 I->getType() == Type::VoidTy) |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
594 break; |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
595 |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
596 // Not captured if only passed via 'nocapture' arguments. Note that |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
597 // calling a function pointer does not in itself cause the pointer to |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
598 // be captured. This is a subtle point considering that (for example) |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
599 // the callee might return its own address. It is analogous to saying |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
600 // that loading a value from a pointer does not cause the pointer to be |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
601 // captured, even though the loaded value might be the pointer itself |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
602 // (think of self-referential objects). |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
603 CallSite::arg_iterator B = CS.arg_begin(), E = CS.arg_end(); |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
604 for (CallSite::arg_iterator A = B; A != E; ++A) |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
605 if (A->get() == V && !CS.paramHasAttr(A - B + 1, Attribute::NoCapture)) |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
606 // The parameter is not marked 'nocapture' - captured. |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
607 return false; |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
608 // Only passed via 'nocapture' arguments, or is the called function - not |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
609 // captured. |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
610 break; |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
611 } |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
612 case Instruction::Free: |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
613 // Freeing a pointer does not cause it to be captured. |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
614 break; |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
615 case Instruction::Load: |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
616 // Loading from a pointer does not cause it to be captured. |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
617 break; |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
618 case Instruction::Store: |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
619 if (V == I->getOperand(0)) |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
620 // Stored the pointer - it may be captured. |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
621 return false; |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
622 // Storing to the pointee does not cause the pointer to be captured. |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
623 break; |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
624 case Instruction::BitCast: |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
625 case Instruction::GetElementPtr: |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
626 case Instruction::PHI: |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
627 case Instruction::Select: |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
628 // It's not safe to stack-allocate if this derived pointer is live across |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
629 // the original allocation. |
1491
360a8e8eea51
Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents:
1488
diff
changeset
|
630 if (mayBeUsedAfterRealloc(I, Alloc, DT)) |
1486
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
631 return false; |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
632 |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
633 // The original value is not captured via this if the new value isn't. |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
634 for (Instruction::use_iterator UI = I->use_begin(), UE = I->use_end(); |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
635 UI != UE; ++UI) { |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
636 Use *U = &UI.getUse(); |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
637 if (Visited.insert(U)) |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
638 Worklist.push_back(U); |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
639 } |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
640 break; |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
641 default: |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
642 // Something else - be conservative and say it is captured. |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
643 return false; |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
644 } |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
645 } |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
646 |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
647 // All uses examined - not captured or live across original allocation. |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
648 return true; |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
649 } |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
650 |
9ed0695cb93c
Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents:
1438
diff
changeset
|
651 |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
652 #endif //USE_METADATA |