Mercurial > projects > ldc
annotate gen/passes/GarbageCollect2Stack.cpp @ 1419:a6dfd3cb5b99 0.9.1
Error instead of assert on delegate literals as constant expressions.
Make function literal linkage internal inside functions and external otherwise.
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Wed, 27 May 2009 19:20:18 +0200 |
parents | 67ac63740c7f |
children | ad999630aa35 |
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" |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
28 #include "llvm/Intrinsics.h" |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
29 #include "llvm/Support/CallSite.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
30 #include "llvm/Support/CommandLine.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
31 #include "llvm/Support/IRBuilder.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
32 #include "llvm/Analysis/CaptureTracking.h" |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
33 #include "llvm/Analysis/ValueTracking.h" |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
34 #include "llvm/Analysis/LoopInfo.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
35 #include "llvm/Target/TargetData.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
36 #include "llvm/ADT/StringMap.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
37 #include "llvm/ADT/Statistic.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
38 #include "llvm/Support/Compiler.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
39 #include "llvm/Support/Debug.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
40 using namespace llvm; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
41 |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
42 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
|
43 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
|
44 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
|
45 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
46 //===----------------------------------------------------------------------===// |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
47 // Helper functions |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
48 //===----------------------------------------------------------------------===// |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
49 |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
50 void EmitMemSet(IRBuilder<>& B, Value* Dst, Value* Val, Value* Len) { |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
51 Dst = B.CreateBitCast(Dst, PointerType::getUnqual(Type::Int8Ty)); |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
52 |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
53 Module *M = B.GetInsertBlock()->getParent()->getParent(); |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
54 const Type* Tys[1]; |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
55 Tys[0] = Len->getType(); |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
56 Value *MemSet = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys, 1); |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
57 Value *Align = ConstantInt::get(Type::Int32Ty, 1); |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
58 |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
59 B.CreateCall4(MemSet, Dst, Val, Len, Align); |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
60 } |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
61 |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
62 static void EmitMemZero(IRBuilder<>& B, Value* Dst, Value* Len) { |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
63 EmitMemSet(B, Dst, ConstantInt::get(Type::Int8Ty, 0), Len); |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
64 } |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
65 |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
66 |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
67 //===----------------------------------------------------------------------===// |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
68 // Helpers for specific types of GC calls. |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
69 //===----------------------------------------------------------------------===// |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
70 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
71 namespace { |
1306 | 72 struct Analysis { |
73 TargetData& TD; | |
74 const Module& M; | |
75 | |
76 const Type* getTypeFor(Value* typeinfo) const; | |
77 }; | |
78 | |
79 class FunctionInfo { | |
80 protected: | |
81 const Type* Ty; | |
82 | |
83 public: | |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
84 unsigned TypeInfoArgNr; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
85 bool SafeToDelete; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
86 |
1306 | 87 // Analyze the current call, filling in some fields. Returns true if |
88 // this is an allocation we can stack-allocate. | |
89 virtual bool analyze(CallSite CS, const Analysis& A) { | |
90 Value* TypeInfo = CS.getArgument(TypeInfoArgNr); | |
91 Ty = A.getTypeFor(TypeInfo); | |
92 return (Ty != NULL); | |
93 } | |
94 | |
95 // Returns the alloca to replace this call. | |
96 // 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
|
97 virtual AllocaInst* promote(CallSite CS, IRBuilder<>& B, const Analysis& A) { |
1306 | 98 NumGcToStack++; |
99 | |
100 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
|
101 return new AllocaInst(Ty, ".nongc_mem", Begin); // FIXME: align? |
1306 | 102 } |
103 | |
104 FunctionInfo(unsigned typeInfoArgNr, bool safeToDelete) | |
105 : TypeInfoArgNr(typeInfoArgNr), SafeToDelete(safeToDelete) {} | |
106 }; | |
107 | |
108 class ArrayFI : public FunctionInfo { | |
109 Value* arrSize; | |
110 int ArrSizeArgNr; | |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
111 bool Initialized; |
1306 | 112 |
113 public: | |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
114 ArrayFI(unsigned tiArgNr, bool safeToDelete, bool initialized, |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
115 unsigned arrSizeArgNr) |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
116 : FunctionInfo(tiArgNr, safeToDelete), |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
117 ArrSizeArgNr(arrSizeArgNr), |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
118 Initialized(initialized) |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
119 {} |
1306 | 120 |
121 virtual bool analyze(CallSite CS, const Analysis& A) { | |
122 if (!FunctionInfo::analyze(CS, A)) | |
123 return false; | |
124 | |
125 arrSize = CS.getArgument(ArrSizeArgNr); | |
126 const IntegerType* SizeType = | |
127 dyn_cast<IntegerType>(arrSize->getType()); | |
128 if (!SizeType) | |
129 return false; | |
130 unsigned bits = SizeType->getBitWidth(); | |
131 if (bits > 32) { | |
132 // The array size of an alloca must be an i32, so make sure | |
133 // the conversion is safe. | |
134 APInt Mask = APInt::getHighBitsSet(bits, bits - 32); | |
135 APInt KnownZero(bits, 0), KnownOne(bits, 0); | |
136 ComputeMaskedBits(arrSize, Mask, KnownZero, KnownOne, &A.TD); | |
137 if ((KnownZero & Mask) != Mask) | |
138 return false; | |
139 } | |
140 // Extract the element type from the array type. | |
141 const StructType* ArrTy = dyn_cast<StructType>(Ty); | |
142 assert(ArrTy && "Dynamic array type not a struct?"); | |
143 assert(isa<IntegerType>(ArrTy->getElementType(0))); | |
144 const PointerType* PtrTy = | |
145 cast<PointerType>(ArrTy->getElementType(1)); | |
146 Ty = PtrTy->getElementType(); | |
147 return true; | |
148 } | |
149 | |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
150 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
|
151 IRBuilder<> Builder = B; |
1306 | 152 // If the allocation is of constant size it's best to put it in the |
153 // entry block, so do so if we're not already there. | |
154 // For dynamically-sized allocations it's best to avoid the overhead | |
155 // of allocating them if possible, so leave those where they are. | |
156 // While we're at it, update statistics too. | |
157 if (isa<Constant>(arrSize)) { | |
158 BasicBlock& Entry = CS.getCaller()->getEntryBlock(); | |
159 if (Builder.GetInsertBlock() != &Entry) | |
160 Builder.SetInsertPoint(&Entry, Entry.begin()); | |
161 NumGcToStack++; | |
162 } else { | |
163 NumToDynSize++; | |
164 } | |
165 | |
166 // 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
|
167 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
|
168 AllocaInst* alloca = Builder.CreateAlloca(Ty, count, ".nongc_mem"); // FIXME: align? |
1306 | 169 |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
170 if (Initialized) { |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
171 // For now, only zero-init is supported. |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
172 uint64_t size = A.TD.getTypeStoreSize(Ty); |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
173 Value* TypeSize = ConstantInt::get(arrSize->getType(), size); |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
174 // 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
|
175 // allocation site. |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
176 Value* Size = B.CreateMul(TypeSize, arrSize); |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
177 EmitMemZero(B, alloca, Size); |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
178 } |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
179 |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
180 return alloca; |
1306 | 181 } |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
182 }; |
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
|
183 |
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
|
184 // 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
|
185 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
|
186 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
|
187 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
|
188 // 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
|
189 // 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
|
190 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
|
191 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
|
192 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
|
193 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
|
194 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
|
195 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
|
196 |
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 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
|
198 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
|
199 |
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 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
|
201 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
|
202 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
|
203 |
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 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
|
205 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
|
206 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
|
207 |
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 // 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
|
209 // 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
|
210 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
|
211 // 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
|
212 // (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
|
213 // those can be ignored) |
1343
c21a6654cce2
Update for metadata changes in LLVM trunk.
Frits van Bommel <fvbommel wxs.nl>
parents:
1317
diff
changeset
|
214 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
|
215 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
|
216 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
|
217 |
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 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
|
219 != 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
|
220 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
|
221 |
1343
c21a6654cce2
Update for metadata changes in LLVM trunk.
Frits van Bommel <fvbommel wxs.nl>
parents:
1317
diff
changeset
|
222 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
|
223 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
|
224 } |
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 |
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
|
226 // 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
|
227 |
1361
67ac63740c7f
silence a gcc warning
Benjamin Kramer <benny.kra@gmail.com>
parents:
1350
diff
changeset
|
228 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
|
229 }; |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
230 } |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
231 |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
232 |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
233 //===----------------------------------------------------------------------===// |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
234 // GarbageCollect2Stack Pass Implementation |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
235 //===----------------------------------------------------------------------===// |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
236 |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
237 namespace { |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
238 /// This pass replaces GC calls with alloca's |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
239 /// |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
240 class VISIBILITY_HIDDEN GarbageCollect2Stack : public FunctionPass { |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
241 StringMap<FunctionInfo*> KnownFunctions; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
242 Module* M; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
243 |
1306 | 244 FunctionInfo AllocMemoryT; |
245 ArrayFI NewArrayVT; | |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
246 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
|
247 AllocClassFI AllocClass; |
1306 | 248 |
249 public: | |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
250 static char ID; // Pass identification |
1306 | 251 GarbageCollect2Stack(); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
252 |
1306 | 253 bool doInitialization(Module &M) { |
254 this->M = &M; | |
255 } | |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
256 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
257 bool runOnFunction(Function &F); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
258 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
259 virtual void getAnalysisUsage(AnalysisUsage &AU) const { |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
260 AU.addRequired<TargetData>(); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
261 AU.addRequired<LoopInfo>(); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
262 } |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
263 }; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
264 char GarbageCollect2Stack::ID = 0; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
265 } // end anonymous namespace. |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
266 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
267 static RegisterPass<GarbageCollect2Stack> |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
268 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
|
269 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
270 // Public interface to the pass. |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
271 FunctionPass *createGarbageCollect2Stack() { |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
272 return new GarbageCollect2Stack(); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
273 } |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
274 |
1306 | 275 GarbageCollect2Stack::GarbageCollect2Stack() |
276 : FunctionPass(&ID), | |
277 AllocMemoryT(0, true), | |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
278 NewArrayVT(0, true, false, 1), |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
279 NewArrayT(0, true, true, 1) |
1306 | 280 { |
281 KnownFunctions["_d_allocmemoryT"] = &AllocMemoryT; | |
282 KnownFunctions["_d_newarrayvT"] = &NewArrayVT; | |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
283 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
|
284 KnownFunctions["_d_allocclass"] = &AllocClass; |
1285
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 |
1298
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
287 static void RemoveCall(Instruction* Inst) { |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
288 if (InvokeInst* Invoke = dyn_cast<InvokeInst>(Inst)) { |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
289 // 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
|
290 // 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
|
291 |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
292 // First notify the exception landing pad block that we won't be |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
293 // going there anymore. |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
294 Invoke->getUnwindDest()->removePredecessor(Invoke->getParent()); |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
295 // Create a branch to the "normal" destination. |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
296 BranchInst::Create(Invoke->getNormalDest(), Invoke->getParent()); |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
297 } |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
298 // Remove the runtime call. |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
299 Inst->eraseFromParent(); |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
300 } |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
301 |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
302 /// runOnFunction - Top level algorithm. |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
303 /// |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
304 bool GarbageCollect2Stack::runOnFunction(Function &F) { |
1295
0e79fb40c4d0
Remove some overly verbose debug output
Frits van Bommel <fvbommel wxs.nl>
parents:
1291
diff
changeset
|
305 DEBUG(DOUT << "Running -dgc2stack on function " << F.getName() << '\n'); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
306 |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
307 TargetData &TD = getAnalysis<TargetData>(); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
308 const LoopInfo &LI = getAnalysis<LoopInfo>(); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
309 |
1306 | 310 Analysis A = { TD, *M }; |
311 | |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
312 BasicBlock& Entry = F.getEntryBlock(); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
313 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
314 IRBuilder<> AllocaBuilder(&Entry, Entry.begin()); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
315 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
316 bool Changed = false; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
317 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
|
318 // We don't yet have sufficient analysis to properly determine if |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
319 // allocations will be unreferenced when the loop returns to their |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
320 // allocation point, so we're playing it safe by ignoring allocations |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
321 // in loops. |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
322 // TODO: Analyze loops too... |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
323 if (LI.getLoopFor(BB)) { |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
324 continue; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
325 } |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
326 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
327 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
|
328 // Ignore non-calls. |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
329 Instruction* Inst = I++; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
330 CallSite CS = CallSite::get(Inst); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
331 if (!CS.getInstruction()) |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
332 continue; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
333 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
334 // 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
|
335 Function *Callee = CS.getCalledFunction(); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
336 if (Callee == 0 || !Callee->isDeclaration() || |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
337 !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage())) |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
338 continue; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
339 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
340 // Ignore unknown calls. |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
341 const char *CalleeName = Callee->getNameStart(); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
342 StringMap<FunctionInfo*>::iterator OMI = |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
343 KnownFunctions.find(CalleeName, CalleeName+Callee->getNameLen()); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
344 if (OMI == KnownFunctions.end()) continue; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
345 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
346 assert(isa<PointerType>(Inst->getType()) |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
347 && "GC function doesn't return a pointer?"); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
348 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
349 FunctionInfo* info = OMI->getValue(); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
350 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
351 if (Inst->use_empty() && info->SafeToDelete) { |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
352 Changed = true; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
353 NumDeleted++; |
1298
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
354 RemoveCall(Inst); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
355 continue; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
356 } |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
357 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
358 DEBUG(DOUT << "GarbageCollect2Stack inspecting: " << *Inst); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
359 |
1306 | 360 if (!info->analyze(CS, A) || PointerMayBeCaptured(Inst, true)) |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
361 continue; |
1305
8215dbf0e09f
Postpone (expensive) escape analysis until we're sure it's needed.
Frits van Bommel <fvbommel wxs.nl>
parents:
1298
diff
changeset
|
362 |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
363 // Let's alloca this! |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
364 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
|
365 |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
366 IRBuilder<> Builder(BB, Inst); |
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
367 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
|
368 |
1343
c21a6654cce2
Update for metadata changes in LLVM trunk.
Frits van Bommel <fvbommel wxs.nl>
parents:
1317
diff
changeset
|
369 DEBUG(DOUT << "Promoted to: " << *newVal); |
c21a6654cce2
Update for metadata changes in LLVM trunk.
Frits van Bommel <fvbommel wxs.nl>
parents:
1317
diff
changeset
|
370 |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
371 // 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
|
372 // 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
|
373 if (newVal->getType() != Inst->getType()) |
1307
e2ec50329af1
Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents:
1306
diff
changeset
|
374 newVal = Builder.CreateBitCast(newVal, Inst->getType()); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
375 Inst->replaceAllUsesWith(newVal); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
376 |
1298
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
377 RemoveCall(Inst); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
378 } |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
379 } |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
380 |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
381 return Changed; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
382 } |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
383 |
1306 | 384 const Type* Analysis::getTypeFor(Value* typeinfo) const { |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
385 GlobalVariable* ti_global = dyn_cast<GlobalVariable>(typeinfo->stripPointerCasts()); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
386 if (!ti_global) |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
387 return NULL; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
388 |
1291
875afb7a93b6
Factor out some constants into the header so producers and consumers of
Frits van Bommel <fvbommel wxs.nl>
parents:
1285
diff
changeset
|
389 std::string metaname = TD_PREFIX; |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
390 metaname.append(ti_global->getNameStart(), ti_global->getNameEnd()); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
391 |
1306 | 392 GlobalVariable* global = M.getGlobalVariable(metaname); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
393 if (!global || !global->hasInitializer()) |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
394 return NULL; |
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 MDNode* node = dyn_cast<MDNode>(global->getInitializer()); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
397 if (!node) |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
398 return NULL; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
399 |
1344
3297edb697eb
Re-enable consistency check for fixed LLVM versions.
Frits van Bommel <fvbommel wxs.nl>
parents:
1343
diff
changeset
|
400 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
|
401 return NULL; |
3297edb697eb
Re-enable consistency check for fixed LLVM versions.
Frits van Bommel <fvbommel wxs.nl>
parents:
1343
diff
changeset
|
402 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
|
403 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
|
404 return NULL; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
405 |
1343
c21a6654cce2
Update for metadata changes in LLVM trunk.
Frits van Bommel <fvbommel wxs.nl>
parents:
1317
diff
changeset
|
406 return MD_GetElement(node, TD_Type)->getType(); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
407 } |
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 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
410 #endif //USE_METADATA |