annotate gen/passes/GarbageCollect2Stack.cpp @ 1306:b61db48127fd

Some refactoring
author Frits van Bommel <fvbommel wxs.nl>
date Wed, 06 May 2009 15:58:15 +0200
parents 8215dbf0e09f
children e2ec50329af1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
28 #include "llvm/Support/CallSite.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
29 #include "llvm/Support/CommandLine.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
30 #include "llvm/Support/IRBuilder.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
31 #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
32 #include "llvm/Analysis/ValueTracking.h"
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
33 #include "llvm/Analysis/LoopInfo.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
34 #include "llvm/Target/TargetData.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
35 #include "llvm/ADT/StringMap.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
36 #include "llvm/ADT/Statistic.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
37 #include "llvm/Support/Compiler.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
38 #include "llvm/Support/Debug.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
39 using namespace llvm;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
40
1297
8e8552601ecd Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents: 1295
diff changeset
41 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
42 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
43 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
44
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 // GarbageCollect2Stack Pass Implementation
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
47 //===----------------------------------------------------------------------===//
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
48
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
49 namespace {
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
50 struct Analysis {
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
51 TargetData& TD;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
52 const Module& M;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
53
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
54 const Type* getTypeFor(Value* typeinfo) const;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
55 };
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
56
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
57 class FunctionInfo {
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
58 protected:
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
59 const Type* Ty;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
60
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
61 public:
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
62 unsigned TypeInfoArgNr;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
63 bool SafeToDelete;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
64
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
65 // Analyze the current call, filling in some fields. Returns true if
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
66 // this is an allocation we can stack-allocate.
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
67 virtual bool analyze(CallSite CS, const Analysis& A) {
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
68 Value* TypeInfo = CS.getArgument(TypeInfoArgNr);
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
69 Ty = A.getTypeFor(TypeInfo);
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
70 return (Ty != NULL);
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
71 }
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
72
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
73 // Returns the alloca to replace this call.
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
74 // It will always be inserted before the call.
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
75 virtual AllocaInst* promote(CallSite CS) {
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
76 NumGcToStack++;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
77
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
78 Instruction* Begin = CS.getCaller()->getEntryBlock().begin();
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
79 return new AllocaInst(Ty, ".nongc_mem", Begin);
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
80 }
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
81
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
82 FunctionInfo(unsigned typeInfoArgNr, bool safeToDelete)
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
83 : TypeInfoArgNr(typeInfoArgNr), SafeToDelete(safeToDelete) {}
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
84 };
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
85
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
86 class ArrayFI : public FunctionInfo {
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
87 Value* arrSize;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
88 int ArrSizeArgNr;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
89
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
90 public:
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
91 ArrayFI(unsigned tiArgNr, bool safeToDelete, unsigned arrSizeArgNr)
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
92 : FunctionInfo(tiArgNr, safeToDelete), ArrSizeArgNr(arrSizeArgNr) {}
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
93
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
94 virtual bool analyze(CallSite CS, const Analysis& A) {
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
95 if (!FunctionInfo::analyze(CS, A))
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
96 return false;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
97
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
98 arrSize = CS.getArgument(ArrSizeArgNr);
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
99 const IntegerType* SizeType =
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
100 dyn_cast<IntegerType>(arrSize->getType());
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
101 if (!SizeType)
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
102 return false;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
103 unsigned bits = SizeType->getBitWidth();
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
104 if (bits > 32) {
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
105 // The array size of an alloca must be an i32, so make sure
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
106 // the conversion is safe.
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
107 APInt Mask = APInt::getHighBitsSet(bits, bits - 32);
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
108 APInt KnownZero(bits, 0), KnownOne(bits, 0);
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
109 ComputeMaskedBits(arrSize, Mask, KnownZero, KnownOne, &A.TD);
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
110 if ((KnownZero & Mask) != Mask)
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
111 return false;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
112 }
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
113 // Extract the element type from the array type.
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
114 const StructType* ArrTy = dyn_cast<StructType>(Ty);
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
115 assert(ArrTy && "Dynamic array type not a struct?");
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
116 assert(isa<IntegerType>(ArrTy->getElementType(0)));
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
117 const PointerType* PtrTy =
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
118 cast<PointerType>(ArrTy->getElementType(1));
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
119 Ty = PtrTy->getElementType();
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
120 return true;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
121 }
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
122
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
123 virtual AllocaInst* promote(CallSite CS) {
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
124 Instruction* I = CS.getInstruction();
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
125 IRBuilder<> Builder(I->getParent(), I);
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
126
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
127 // If the allocation is of constant size it's best to put it in the
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
128 // entry block, so do so if we're not already there.
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
129 // For dynamically-sized allocations it's best to avoid the overhead
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
130 // of allocating them if possible, so leave those where they are.
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
131 // While we're at it, update statistics too.
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
132 if (isa<Constant>(arrSize)) {
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
133 BasicBlock& Entry = CS.getCaller()->getEntryBlock();
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
134 if (Builder.GetInsertBlock() != &Entry)
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
135 Builder.SetInsertPoint(&Entry, Entry.begin());
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
136 NumGcToStack++;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
137 } else {
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
138 NumToDynSize++;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
139 }
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
140
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
141 // Convert array size to 32 bits if necessary
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
142 arrSize = Builder.CreateIntCast(arrSize, Type::Int32Ty, false);
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
143
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
144 return Builder.CreateAlloca(Ty, arrSize, ".nongc_mem");
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
145 }
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
146 };
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
147
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
148 /// This pass replaces GC calls with alloca's
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
149 ///
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
150 class VISIBILITY_HIDDEN GarbageCollect2Stack : public FunctionPass {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
151 StringMap<FunctionInfo*> KnownFunctions;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
152 Module* M;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
153
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
154 FunctionInfo AllocMemoryT;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
155 ArrayFI NewArrayVT;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
156
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
157 public:
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
158 static char ID; // Pass identification
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
159 GarbageCollect2Stack();
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
160
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
161 bool doInitialization(Module &M) {
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
162 this->M = &M;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
163 }
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
164
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
165 bool runOnFunction(Function &F);
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
166
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
167 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
168 AU.addRequired<TargetData>();
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
169 AU.addRequired<LoopInfo>();
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
170 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
171 };
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
172 char GarbageCollect2Stack::ID = 0;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
173 } // end anonymous namespace.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
174
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
175 static RegisterPass<GarbageCollect2Stack>
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
176 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
177
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
178 // Public interface to the pass.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
179 FunctionPass *createGarbageCollect2Stack() {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
180 return new GarbageCollect2Stack();
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
181 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
182
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
183 GarbageCollect2Stack::GarbageCollect2Stack()
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
184 : FunctionPass(&ID),
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
185 AllocMemoryT(0, true),
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
186 NewArrayVT(0, true, 1)
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
187 {
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
188 KnownFunctions["_d_allocmemoryT"] = &AllocMemoryT;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
189 KnownFunctions["_d_newarrayvT"] = &NewArrayVT;
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
190 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
191
1298
7e303f9f16c7 Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents: 1297
diff changeset
192 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
193 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
194 // 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
195 // 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
196
7e303f9f16c7 Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents: 1297
diff changeset
197 // 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
198 // 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
199 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
200 // 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
201 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
202 }
7e303f9f16c7 Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents: 1297
diff changeset
203 // 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
204 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
205 }
7e303f9f16c7 Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents: 1297
diff changeset
206
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
207 /// runOnFunction - Top level algorithm.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
208 ///
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
209 bool GarbageCollect2Stack::runOnFunction(Function &F) {
1295
0e79fb40c4d0 Remove some overly verbose debug output
Frits van Bommel <fvbommel wxs.nl>
parents: 1291
diff changeset
210 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
211
1297
8e8552601ecd Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents: 1295
diff changeset
212 TargetData &TD = getAnalysis<TargetData>();
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
213 const LoopInfo &LI = getAnalysis<LoopInfo>();
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
214
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
215 Analysis A = { TD, *M };
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
216
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
217 BasicBlock& Entry = F.getEntryBlock();
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
218
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
219 IRBuilder<> AllocaBuilder(&Entry, Entry.begin());
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
220
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
221 bool Changed = false;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
222 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
223 // 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
224 // 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
225 // 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
226 // in loops.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
227 // TODO: Analyze loops too...
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
228 if (LI.getLoopFor(BB)) {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
229 continue;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
230 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
231
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
232 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
233 // Ignore non-calls.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
234 Instruction* Inst = I++;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
235 CallSite CS = CallSite::get(Inst);
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
236 if (!CS.getInstruction())
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
237 continue;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
238
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
239 // 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
240 Function *Callee = CS.getCalledFunction();
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
241 if (Callee == 0 || !Callee->isDeclaration() ||
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
242 !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage()))
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
243 continue;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
244
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
245 // Ignore unknown calls.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
246 const char *CalleeName = Callee->getNameStart();
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
247 StringMap<FunctionInfo*>::iterator OMI =
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
248 KnownFunctions.find(CalleeName, CalleeName+Callee->getNameLen());
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
249 if (OMI == KnownFunctions.end()) continue;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
250
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
251 assert(isa<PointerType>(Inst->getType())
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
252 && "GC function doesn't return a pointer?");
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
253
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
254 FunctionInfo* info = OMI->getValue();
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
255
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
256 if (Inst->use_empty() && info->SafeToDelete) {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
257 Changed = true;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
258 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
259 RemoveCall(Inst);
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
260 continue;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
261 }
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 DEBUG(DOUT << "GarbageCollect2Stack inspecting: " << *Inst);
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
264
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
265 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
266 continue;
1305
8215dbf0e09f Postpone (expensive) escape analysis until we're sure it's needed.
Frits van Bommel <fvbommel wxs.nl>
parents: 1298
diff changeset
267
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
268 // Let's alloca this!
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
269 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
270
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
271 Value* newVal = info->promote(CS);
1297
8e8552601ecd Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents: 1295
diff changeset
272
8e8552601ecd Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents: 1295
diff changeset
273 // 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
274 // 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
275 if (newVal->getType() != Inst->getType())
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
276 newVal = new BitCastInst(newVal, Inst->getType(), "", Inst);
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
277 Inst->replaceAllUsesWith(newVal);
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
278
1298
7e303f9f16c7 Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents: 1297
diff changeset
279 RemoveCall(Inst);
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
280 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
281 }
1297
8e8552601ecd Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents: 1295
diff changeset
282
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
283 return Changed;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
284 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
285
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
286 const Type* Analysis::getTypeFor(Value* typeinfo) const {
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
287 GlobalVariable* ti_global = dyn_cast<GlobalVariable>(typeinfo->stripPointerCasts());
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
288 if (!ti_global)
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
289 return NULL;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
290
1291
875afb7a93b6 Factor out some constants into the header so producers and consumers of
Frits van Bommel <fvbommel wxs.nl>
parents: 1285
diff changeset
291 std::string metaname = TD_PREFIX;
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
292 metaname.append(ti_global->getNameStart(), ti_global->getNameEnd());
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
293
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
294 GlobalVariable* global = M.getGlobalVariable(metaname);
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
295 if (!global || !global->hasInitializer())
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
296 return NULL;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
297
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
298 MDNode* node = dyn_cast<MDNode>(global->getInitializer());
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
299 if (!node)
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
300 return NULL;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
301
1291
875afb7a93b6 Factor out some constants into the header so producers and consumers of
Frits van Bommel <fvbommel wxs.nl>
parents: 1285
diff changeset
302 if (node->getNumOperands() != TD_NumFields ||
875afb7a93b6 Factor out some constants into the header so producers and consumers of
Frits van Bommel <fvbommel wxs.nl>
parents: 1285
diff changeset
303 node->getOperand(TD_Confirm)->stripPointerCasts() != ti_global)
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
304 return NULL;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
305
1291
875afb7a93b6 Factor out some constants into the header so producers and consumers of
Frits van Bommel <fvbommel wxs.nl>
parents: 1285
diff changeset
306 return node->getOperand(TD_Type)->getType();
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
307 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
308
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
309
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
310 #endif //USE_METADATA