annotate gen/passes/GarbageCollect2Stack.cpp @ 1554:d6e8d5db259f

LLVMContext changes up to r77366
author Benjamin Kramer <benny.kra@gmail.com>
date Thu, 30 Jul 2009 15:25:10 +0200
parents f55ca8a1598c
children ed0cffe895ec
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
1 //===- GarbageCollect2Stack - Optimize calls to the D garbage collector ---===//
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
2 //
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
3 // The LLVM D Compiler
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
4 //
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
5 // This file is distributed under the University of Illinois Open Source
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
6 // License. See LICENSE.TXT for details.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
7 //
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
8 //===----------------------------------------------------------------------===//
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
9 //
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
10 // This file attempts to turn allocations on the garbage-collected heap into
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
11 // stack allocations.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
12 //
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
13 //===----------------------------------------------------------------------===//
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
14
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
15 #include "gen/metadata.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
16
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
17 #define DEBUG_TYPE "dgc2stack"
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 #include "Passes.h"
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 "llvm/Pass.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
22 #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
23 #include "llvm/Constants.h"
1307
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
24 #include "llvm/Intrinsics.h"
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
25 #include "llvm/Support/CallSite.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
26 #include "llvm/Support/CommandLine.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
27 #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
28 #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
29 #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
30 #include "llvm/Analysis/ValueTracking.h"
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
31 #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
32 #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
33 #include "llvm/ADT/SmallVector.h"
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
34 #include "llvm/ADT/StringMap.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
35 #include "llvm/ADT/Statistic.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
36 #include "llvm/Support/Compiler.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
37 #include "llvm/Support/Debug.h"
1551
ed0feda76820 DOUT is deprecated, use DEBUG(errs()) instead
Benjamin Kramer <benny.kra@gmail.com>
parents: 1548
diff changeset
38 #include "llvm/Support/raw_ostream.h"
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
39 using namespace llvm;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
40
1297
8e8552601ecd Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents: 1295
diff changeset
41 STATISTIC(NumGcToStack, "Number of calls promoted to constant-size allocas");
8e8552601ecd Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents: 1295
diff changeset
42 STATISTIC(NumToDynSize, "Number of calls promoted to dynamically-sized allocas");
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
43 STATISTIC(NumDeleted, "Number of GC calls deleted because the return value was unused");
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
44
1424
ad999630aa35 Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents: 1361
diff changeset
45
ad999630aa35 Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents: 1361
diff changeset
46 namespace {
ad999630aa35 Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents: 1361
diff changeset
47 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
48 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
49 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
50 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
51 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
52
ad999630aa35 Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents: 1361
diff changeset
53 const 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
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 }
ad999630aa35 Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents: 1361
diff changeset
56
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
57 //===----------------------------------------------------------------------===//
1307
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
58 // Helper functions
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
59 //===----------------------------------------------------------------------===//
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
60
1554
d6e8d5db259f LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents: 1553
diff changeset
61 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
62 const Analysis& A) {
1307
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
63 Dst = B.CreateBitCast(Dst, PointerType::getUnqual(Type::Int8Ty));
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
64
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
65 Module *M = B.GetInsertBlock()->getParent()->getParent();
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
66 const Type* Tys[1];
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
67 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
68 Function *MemSet = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys, 1);
1554
d6e8d5db259f LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents: 1553
diff changeset
69 Value *Align = ConstantInt::get(Type::Int32Ty, 1);
1307
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
70
1424
ad999630aa35 Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents: 1361
diff changeset
71 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
72 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
73 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
74 }
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
75
1554
d6e8d5db259f LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents: 1553
diff changeset
76 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
77 const Analysis& A) {
d6e8d5db259f LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents: 1553
diff changeset
78 EmitMemSet(B, Dst, ConstantInt::get(Type::Int8Ty, 0), Len, A);
1307
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
79 }
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
80
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 // Helpers for specific types of GC calls.
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
84 //===----------------------------------------------------------------------===//
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
85
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
86 namespace {
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
87 class FunctionInfo {
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
88 protected:
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
89 const Type* Ty;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
90
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
91 public:
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
92 unsigned TypeInfoArgNr;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
93 bool SafeToDelete;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
94
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
95 // Analyze the current call, filling in some fields. Returns true if
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
96 // 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
97 virtual bool analyze(CallSite CS, const Analysis& A) {
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
98 Value* TypeInfo = CS.getArgument(TypeInfoArgNr);
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
99 Ty = A.getTypeFor(TypeInfo);
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
100 return (Ty != NULL);
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
101 }
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
102
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
103 // Returns the alloca to replace this call.
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
104 // 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
105 virtual AllocaInst* promote(CallSite CS, IRBuilder<>& B, const Analysis& A) {
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
106 NumGcToStack++;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
107
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
108 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
109 return new AllocaInst(Ty, ".nongc_mem", Begin); // FIXME: align?
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
110 }
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
111
1548
a326f145a57b ConstantInt::get{True,False} moved to LLVMContext
Benjamin Kramer <benny.kra@gmail.com>
parents: 1545
diff changeset
112 FunctionInfo(unsigned typeInfoArgNr, bool safeToDelete)
a326f145a57b ConstantInt::get{True,False} moved to LLVMContext
Benjamin Kramer <benny.kra@gmail.com>
parents: 1545
diff changeset
113 : TypeInfoArgNr(typeInfoArgNr), SafeToDelete(safeToDelete) {}
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
114 };
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
115
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
116 class ArrayFI : public FunctionInfo {
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
117 Value* arrSize;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
118 int ArrSizeArgNr;
1307
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
119 bool Initialized;
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
120
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
121 public:
1554
d6e8d5db259f LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents: 1553
diff changeset
122 ArrayFI(unsigned tiArgNr, bool safeToDelete, bool initialized,
d6e8d5db259f LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents: 1553
diff changeset
123 unsigned arrSizeArgNr)
1548
a326f145a57b ConstantInt::get{True,False} moved to LLVMContext
Benjamin Kramer <benny.kra@gmail.com>
parents: 1545
diff changeset
124 : FunctionInfo(tiArgNr, safeToDelete),
1307
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
125 ArrSizeArgNr(arrSizeArgNr),
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
126 Initialized(initialized)
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
127 {}
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
128
1554
d6e8d5db259f LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents: 1553
diff changeset
129 virtual bool analyze(CallSite CS, const Analysis& A) {
d6e8d5db259f LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents: 1553
diff changeset
130 if (!FunctionInfo::analyze(CS, A))
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
131 return false;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
132
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
133 arrSize = CS.getArgument(ArrSizeArgNr);
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
134 const IntegerType* SizeType =
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
135 dyn_cast<IntegerType>(arrSize->getType());
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
136 if (!SizeType)
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
137 return false;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
138 unsigned bits = SizeType->getBitWidth();
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
139 if (bits > 32) {
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
140 // 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
141 // the conversion is safe.
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
142 APInt Mask = APInt::getHighBitsSet(bits, bits - 32);
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
143 APInt KnownZero(bits, 0), KnownOne(bits, 0);
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
144 ComputeMaskedBits(arrSize, Mask, KnownZero, KnownOne, &A.TD);
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
145 if ((KnownZero & Mask) != Mask)
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
146 return false;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
147 }
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
148 // Extract the element type from the array type.
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
149 const StructType* ArrTy = dyn_cast<StructType>(Ty);
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
150 assert(ArrTy && "Dynamic array type not a struct?");
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
151 assert(isa<IntegerType>(ArrTy->getElementType(0)));
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
152 const PointerType* PtrTy =
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
153 cast<PointerType>(ArrTy->getElementType(1));
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
154 Ty = PtrTy->getElementType();
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
155 return true;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
156 }
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
157
1554
d6e8d5db259f LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents: 1553
diff changeset
158 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
159 IRBuilder<> Builder = B;
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
160 // 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
161 // entry block, so do so if we're not already there.
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
162 // For dynamically-sized allocations it's best to avoid the overhead
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
163 // of allocating them if possible, so leave those where they are.
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
164 // While we're at it, update statistics too.
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
165 if (isa<Constant>(arrSize)) {
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
166 BasicBlock& Entry = CS.getCaller()->getEntryBlock();
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
167 if (Builder.GetInsertBlock() != &Entry)
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
168 Builder.SetInsertPoint(&Entry, Entry.begin());
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
169 NumGcToStack++;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
170 } else {
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
171 NumToDynSize++;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
172 }
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
173
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
174 // Convert array size to 32 bits if necessary
1307
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
175 Value* count = Builder.CreateIntCast(arrSize, Type::Int32Ty, false);
1350
15e9762bb620 Adds explicit alignment information for alloca instructions in general, there's a few cases that still needs to be looked at but this should catch the majority. Fixes ticket #293 .
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents: 1344
diff changeset
176 AllocaInst* alloca = Builder.CreateAlloca(Ty, count, ".nongc_mem"); // FIXME: align?
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
177
1307
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
178 if (Initialized) {
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
179 // For now, only zero-init is supported.
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
180 uint64_t size = A.TD.getTypeStoreSize(Ty);
1554
d6e8d5db259f LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents: 1553
diff changeset
181 Value* TypeSize = ConstantInt::get(arrSize->getType(), size);
1307
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
182 // 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
183 // allocation site.
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
184 Value* Size = B.CreateMul(TypeSize, arrSize);
1554
d6e8d5db259f LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents: 1553
diff changeset
185 EmitMemZero(B, alloca, Size, A);
1307
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
186 }
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
187
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
188 return alloca;
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
189 }
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
190 };
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
191
4099548c80e0 Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents: 1316
diff changeset
192 // 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
193 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
194 public:
1554
d6e8d5db259f LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents: 1553
diff changeset
195 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
196 // 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
197 // 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
198 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
199 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
200 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
201 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
202 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
203 return false;
4099548c80e0 Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents: 1316
diff changeset
204
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 std::string metaname = CD_PREFIX;
1553
f55ca8a1598c Value::getNameStart and Value::getNameLength were removed
Benjamin Kramer <benny.kra@gmail.com>
parents: 1551
diff changeset
206 metaname += ClassInfo->getName();
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
4099548c80e0 Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents: 1316
diff changeset
208 GlobalVariable* global = A.M.getGlobalVariable(metaname);
4099548c80e0 Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents: 1316
diff changeset
209 if (!global || !global->hasInitializer())
4099548c80e0 Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents: 1316
diff changeset
210 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
211
4099548c80e0 Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents: 1316
diff changeset
212 MDNode* node = dyn_cast<MDNode>(global->getInitializer());
1343
c21a6654cce2 Update for metadata changes in LLVM trunk.
Frits van Bommel <fvbommel wxs.nl>
parents: 1317
diff changeset
213 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
214 return false;
4099548c80e0 Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents: 1316
diff changeset
215
4099548c80e0 Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents: 1316
diff changeset
216 // 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
217 // 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
218 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
219 // 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
220 // (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
221 // those can be ignored)
1343
c21a6654cce2 Update for metadata changes in LLVM trunk.
Frits van Bommel <fvbommel wxs.nl>
parents: 1317
diff changeset
222 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
223 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
224 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
225
1554
d6e8d5db259f LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents: 1553
diff changeset
226 if (ConstantExpr::getOr(hasDestructor, hasCustomDelete)
d6e8d5db259f LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents: 1553
diff changeset
227 != A.M.getContext().getFalse())
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
228 return false;
4099548c80e0 Allocate objects on the stack if they (a) don't have a destructor, and
Frits van Bommel <fvbommel wxs.nl>
parents: 1316
diff changeset
229
1343
c21a6654cce2 Update for metadata changes in LLVM trunk.
Frits van Bommel <fvbommel wxs.nl>
parents: 1317
diff changeset
230 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
231 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
232 }
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
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 // 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
235
1548
a326f145a57b ConstantInt::get{True,False} moved to LLVMContext
Benjamin Kramer <benny.kra@gmail.com>
parents: 1545
diff changeset
236 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
237 };
1307
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
238 }
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
239
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 // GarbageCollect2Stack Pass Implementation
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
243 //===----------------------------------------------------------------------===//
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
244
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
245 namespace {
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
246 /// This pass replaces GC calls with alloca's
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
247 ///
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
248 class VISIBILITY_HIDDEN GarbageCollect2Stack : public FunctionPass {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
249 StringMap<FunctionInfo*> KnownFunctions;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
250 Module* M;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
251
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
252 FunctionInfo AllocMemoryT;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
253 ArrayFI NewArrayVT;
1307
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
254 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
255 AllocClassFI AllocClass;
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
256
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
257 public:
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
258 static char ID; // Pass identification
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
259 GarbageCollect2Stack();
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
260
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
261 bool doInitialization(Module &M) {
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
262 this->M = &M;
1438
c363d131c1ef Add some missing returns.
Frits van Bommel <fvbommel wxs.nl>
parents: 1424
diff changeset
263 return false;
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
264 }
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
265
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
266 bool runOnFunction(Function &F);
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 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
269 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
270 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
271
1424
ad999630aa35 Teach -dgc2stack to preserve the call graph. This should allow for more
Frits van Bommel <fvbommel wxs.nl>
parents: 1361
diff changeset
272 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
273 AU.addPreserved<DominatorTree>();
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
274 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
275 };
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
276 char GarbageCollect2Stack::ID = 0;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
277 } // end anonymous namespace.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
278
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
279 static RegisterPass<GarbageCollect2Stack>
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
280 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
281
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
282 // Public interface to the pass.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
283 FunctionPass *createGarbageCollect2Stack() {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
284 return new GarbageCollect2Stack();
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
285 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
286
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
287 GarbageCollect2Stack::GarbageCollect2Stack()
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
288 : FunctionPass(&ID),
1548
a326f145a57b ConstantInt::get{True,False} moved to LLVMContext
Benjamin Kramer <benny.kra@gmail.com>
parents: 1545
diff changeset
289 AllocMemoryT(0, true),
a326f145a57b ConstantInt::get{True,False} moved to LLVMContext
Benjamin Kramer <benny.kra@gmail.com>
parents: 1545
diff changeset
290 NewArrayVT(0, true, false, 1),
a326f145a57b ConstantInt::get{True,False} moved to LLVMContext
Benjamin Kramer <benny.kra@gmail.com>
parents: 1545
diff changeset
291 NewArrayT(0, true, true, 1)
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
292 {
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
293 KnownFunctions["_d_allocmemoryT"] = &AllocMemoryT;
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
294 KnownFunctions["_d_newarrayvT"] = &NewArrayVT;
1307
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
295 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
296 KnownFunctions["_d_allocclass"] = &AllocClass;
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
297 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
298
1554
d6e8d5db259f LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents: 1553
diff changeset
299 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
300 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
301 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
302 // 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
303 // 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
304
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
305 // 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
306 // 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
307 BranchInst::Create(Invoke->getNormalDest(), Invoke->getUnwindDest(),
1554
d6e8d5db259f LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents: 1553
diff changeset
308 A.M.getContext().getTrue(), Invoke->getParent());
1298
7e303f9f16c7 Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents: 1297
diff changeset
309 }
7e303f9f16c7 Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents: 1297
diff changeset
310 // 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
311 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
312 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
313 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
314 }
7e303f9f16c7 Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents: 1297
diff changeset
315
1488
ca31a8e9c42b Oops, I accidentally pushed r1486 before the last touches were committed.
Frits van Bommel <fvbommel wxs.nl>
parents: 1486
diff changeset
316 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
317
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
318 /// runOnFunction - Top level algorithm.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
319 ///
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
320 bool GarbageCollect2Stack::runOnFunction(Function &F) {
1551
ed0feda76820 DOUT is deprecated, use DEBUG(errs()) instead
Benjamin Kramer <benny.kra@gmail.com>
parents: 1548
diff changeset
321 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
322
1486
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
323 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
324 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
325 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
326 CallGraphNode* CGNode = CG ? (*CG)[&F] : NULL;
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
327
1488
ca31a8e9c42b Oops, I accidentally pushed r1486 before the last touches were committed.
Frits van Bommel <fvbommel wxs.nl>
parents: 1486
diff changeset
328 Analysis A = { TD, *M, CG, CGNode };
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
329
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
330 BasicBlock& Entry = F.getEntryBlock();
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
331
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
332 IRBuilder<> AllocaBuilder(&Entry, Entry.begin());
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 bool Changed = false;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
335 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
336 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
337 // Ignore non-calls.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
338 Instruction* Inst = I++;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
339 CallSite CS = CallSite::get(Inst);
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
340 if (!CS.getInstruction())
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
341 continue;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
342
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
343 // 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
344 Function *Callee = CS.getCalledFunction();
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
345 if (Callee == 0 || !Callee->isDeclaration() ||
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
346 !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage()))
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
347 continue;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
348
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
349 // Ignore unknown calls.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
350 StringMap<FunctionInfo*>::iterator OMI =
1553
f55ca8a1598c Value::getNameStart and Value::getNameLength were removed
Benjamin Kramer <benny.kra@gmail.com>
parents: 1551
diff changeset
351 KnownFunctions.find(Callee->getName());
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
352 if (OMI == KnownFunctions.end()) continue;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
353
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
354 assert(isa<PointerType>(Inst->getType())
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
355 && "GC function doesn't return a pointer?");
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
356
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
357 FunctionInfo* info = OMI->getValue();
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 if (Inst->use_empty() && info->SafeToDelete) {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
360 Changed = true;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
361 NumDeleted++;
1554
d6e8d5db259f LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents: 1553
diff changeset
362 RemoveCall(CS, A);
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
363 continue;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
364 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
365
1551
ed0feda76820 DOUT is deprecated, use DEBUG(errs()) instead
Benjamin Kramer <benny.kra@gmail.com>
parents: 1548
diff changeset
366 DEBUG(errs() << "GarbageCollect2Stack inspecting: " << *Inst);
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
367
1554
d6e8d5db259f LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents: 1553
diff changeset
368 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
369 continue;
1305
8215dbf0e09f Postpone (expensive) escape analysis until we're sure it's needed.
Frits van Bommel <fvbommel wxs.nl>
parents: 1298
diff changeset
370
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
371 // Let's alloca this!
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
372 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
373
1307
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
374 IRBuilder<> Builder(BB, Inst);
1554
d6e8d5db259f LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents: 1553
diff changeset
375 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
376
1551
ed0feda76820 DOUT is deprecated, use DEBUG(errs()) instead
Benjamin Kramer <benny.kra@gmail.com>
parents: 1548
diff changeset
377 DEBUG(errs() << "Promoted to: " << *newVal);
1343
c21a6654cce2 Update for metadata changes in LLVM trunk.
Frits van Bommel <fvbommel wxs.nl>
parents: 1317
diff changeset
378
1297
8e8552601ecd Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents: 1295
diff changeset
379 // 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
380 // 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
381 if (newVal->getType() != Inst->getType())
1307
e2ec50329af1 Stack-allocate zero-initialized arrays.
Frits van Bommel <fvbommel wxs.nl>
parents: 1306
diff changeset
382 newVal = Builder.CreateBitCast(newVal, Inst->getType());
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
383 Inst->replaceAllUsesWith(newVal);
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
384
1554
d6e8d5db259f LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents: 1553
diff changeset
385 RemoveCall(CS, A);
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
386 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
387 }
1297
8e8552601ecd Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents: 1295
diff changeset
388
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
389 return Changed;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
390 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
391
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
392 const Type* Analysis::getTypeFor(Value* typeinfo) const {
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
393 GlobalVariable* ti_global = dyn_cast<GlobalVariable>(typeinfo->stripPointerCasts());
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
394 if (!ti_global)
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
395 return NULL;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
396
1291
875afb7a93b6 Factor out some constants into the header so producers and consumers of
Frits van Bommel <fvbommel wxs.nl>
parents: 1285
diff changeset
397 std::string metaname = TD_PREFIX;
1553
f55ca8a1598c Value::getNameStart and Value::getNameLength were removed
Benjamin Kramer <benny.kra@gmail.com>
parents: 1551
diff changeset
398 metaname += ti_global->getName();
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
399
1306
b61db48127fd Some refactoring
Frits van Bommel <fvbommel wxs.nl>
parents: 1305
diff changeset
400 GlobalVariable* global = M.getGlobalVariable(metaname);
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
401 if (!global || !global->hasInitializer())
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
402 return NULL;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
403
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
404 MDNode* node = dyn_cast<MDNode>(global->getInitializer());
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
405 if (!node)
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
406 return NULL;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
407
1344
3297edb697eb Re-enable consistency check for fixed LLVM versions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1343
diff changeset
408 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
409 return NULL;
3297edb697eb Re-enable consistency check for fixed LLVM versions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1343
diff changeset
410 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
411 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
412 return NULL;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
413
1343
c21a6654cce2 Update for metadata changes in LLVM trunk.
Frits van Bommel <fvbommel wxs.nl>
parents: 1317
diff changeset
414 return MD_GetElement(node, TD_Type)->getType();
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
415 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
416
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
417 /// 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
418 /// (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
419 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
420 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
421
360a8e8eea51 Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents: 1488
diff changeset
422 // 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
423 // 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
424 // 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
425 // 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
426 // 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
427 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
428 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
429 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
430 }
360a8e8eea51 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
1551
ed0feda76820 DOUT is deprecated, use DEBUG(errs()) instead
Benjamin Kramer <benny.kra@gmail.com>
parents: 1548
diff changeset
432 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
433
360a8e8eea51 Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents: 1488
diff changeset
434 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
435 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
436
360a8e8eea51 Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents: 1488
diff changeset
437 // 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
438 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
439 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
440 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
441 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
442 Instruction* User = cast<Instruction>(*UI);
1551
ed0feda76820 DOUT is deprecated, use DEBUG(errs()) instead
Benjamin Kramer <benny.kra@gmail.com>
parents: 1548
diff changeset
443 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
444 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
445
360a8e8eea51 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 // 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
447 // 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
448 // 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
449 // 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
450 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
451 // 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
452 // 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
453 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
454 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
455 }
360a8e8eea51 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
360a8e8eea51 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 // 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
458 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
459 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
460 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
461 }
360a8e8eea51 Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents: 1488
diff changeset
462 }
360a8e8eea51 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 // 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
465 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
466 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
467 // 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
468 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
469
360a8e8eea51 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 // 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
471 // 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
472 // 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
473 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
474 ++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
475 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
476
360a8e8eea51 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 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
478 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
479 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
480 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
481 // 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
482 // 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
483
360a8e8eea51 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 // 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
485 // 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
486 // 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
487 // 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
488 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
489 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
490 // 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
491 // 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
492 // 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
493 DEBUG(errs() << "### Block " << B->getName()
ed0feda76820 DOUT is deprecated, use DEBUG(errs()) instead
Benjamin Kramer <benny.kra@gmail.com>
parents: 1548
diff changeset
494 << " 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
495 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
496 }
360a8e8eea51 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 // 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
498 // 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
499 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
500 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
501 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
502 if (Users.count(BBI)) {
1551
ed0feda76820 DOUT is deprecated, use DEBUG(errs()) instead
Benjamin Kramer <benny.kra@gmail.com>
parents: 1548
diff changeset
503 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
504 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
505 }
360a8e8eea51 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 }
360a8e8eea51 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 } 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
508 // 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
509 // 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
510 // 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
511 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
512 } 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
513 // 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
514 // 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
515 }
360a8e8eea51 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
360a8e8eea51 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 // 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
518 // 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
519 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
520 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
521 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
522 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
523 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
524 // 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
525 // 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
526 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
527 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
528 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
529 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
530 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
531 }
360a8e8eea51 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 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
533 ++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
534 }
360a8e8eea51 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 // 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
536 // 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
537 // (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
538 // 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
539 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
540 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
541 }
360a8e8eea51 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 }
360a8e8eea51 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 // 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
544 // 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
545 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
546 }
360a8e8eea51 Teach stack promotion to walk the CFG when a potential reuse of an allocation
Frits van Bommel <fvbommel wxs.nl>
parents: 1488
diff changeset
547
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
548
1486
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
549 /// 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
550 /// 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
551 /// 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
552 /// (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
553 /// 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
554 ///
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
555 /// 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
556 /// 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
557 /// subsequent iteration.
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
558 ///
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
559 /// 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
560 /// 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
561 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
562 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
563 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
564
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
565 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
566 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
567
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
568 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
569 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
570 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
571 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
572 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
573 }
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
574
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
575 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
576 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
577 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
578 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
579
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
580 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
581 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
582 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
583 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
584 // 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
585 // 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
586 // 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
587 if (CS.onlyReadsMemory() && CS.doesNotThrow() &&
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
588 I->getType() == Type::VoidTy)
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
589 break;
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
590
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
591 // 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
592 // 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
593 // 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
594 // 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
595 // 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
596 // 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
597 // (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
598 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
599 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
600 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
601 // 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
602 return false;
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
603 // 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
604 // captured.
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
605 break;
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
606 }
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
607 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
608 // 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
609 break;
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
610 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
611 // 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
612 break;
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
613 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
614 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
615 // 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
616 return false;
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
617 // 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
618 break;
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
619 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
620 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
621 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
622 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
623 // 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
624 // 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
625 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
626 return false;
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
627
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
628 // 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
629 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
630 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
631 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
632 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
633 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
634 }
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
635 break;
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
636 default:
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
637 // 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
638 return false;
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
639 }
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
640 }
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 // 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
643 return true;
9ed0695cb93c Teach `-dgc2stack` to promote GC allocations in simple loops to stack
Frits van Bommel <fvbommel wxs.nl>
parents: 1438
diff changeset
644 }