annotate gen/passes/GarbageCollect2Stack.cpp @ 1650:40bd4a0d4870

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