15
15
16
16
#include < vector>
17
17
#include < queue>
18
+ #include < set>
18
19
19
20
#include " julia.h"
20
21
@@ -36,7 +37,7 @@ static struct {
36
37
37
38
class JuliaGCAllocator {
38
39
public:
39
- JuliaGCAllocator (CallInst *ptlsStates, Type *T_pjlvalue) :
40
+ JuliaGCAllocator (CallInst *ptlsStates, Type *T_pjlvalue, MDNode *tbaa ) :
40
41
F (*ptlsStates->getParent ()->getParent()),
41
42
M(*F.getParent()),
42
43
T_int32(Type::getInt32Ty(F.getContext())),
@@ -47,7 +48,8 @@ class JuliaGCAllocator {
47
48
gcroot_func(M.getFunction(" julia.gc_root_decl" )),
48
49
gckill_func(M.getFunction(" julia.gc_root_kill" )),
49
50
gc_store_func(M.getFunction(" julia.gc_store" )),
50
- jlcall_frame_func(M.getFunction(" julia.jlcall_frame_decl" ))
51
+ jlcall_frame_func(M.getFunction(" julia.jlcall_frame_decl" )),
52
+ tbaa_gcframe(tbaa)
51
53
{
52
54
/* Algorithm sketch:
53
55
* Compute liveness for each basic block
@@ -74,6 +76,7 @@ Function *const gcroot_func;
74
76
Function *const gckill_func;
75
77
Function *const gc_store_func;
76
78
Function *const jlcall_frame_func;
79
+ MDNode *tbaa_gcframe;
77
80
78
81
typedef std::pair<CallInst*, unsigned > frame_register;
79
82
class liveness {
@@ -90,6 +93,42 @@ class liveness {
90
93
};
91
94
};
92
95
96
+ void tbaa_decorate_gcframe (Instruction *inst, std::set<Instruction*> &visited)
97
+ {
98
+ if (visited.find (inst) != visited.end ())
99
+ return ;
100
+ visited.insert (inst);
101
+ #ifdef LLVM35
102
+ Value::user_iterator I = inst->user_begin (), E = inst->user_end ();
103
+ #else
104
+ Value::use_iterator I = inst->use_begin (), E = inst->use_end ();
105
+ #endif
106
+ for (;I != E;++I) {
107
+ Instruction *user = dyn_cast<Instruction>(*I);
108
+ if (!user) {
109
+ continue ;
110
+ } else if (isa<GetElementPtrInst>(user)) {
111
+ if (__likely (user->getOperand (0 ) == inst)) {
112
+ tbaa_decorate_gcframe (user, visited);
113
+ }
114
+ } else if (isa<StoreInst>(user)) {
115
+ if (user->getOperand (1 ) == inst) {
116
+ user->setMetadata (llvm::LLVMContext::MD_tbaa, tbaa_gcframe);
117
+ }
118
+ } else if (isa<LoadInst>(user)) {
119
+ user->setMetadata (llvm::LLVMContext::MD_tbaa, tbaa_gcframe);
120
+ } else if (isa<BitCastInst>(user)) {
121
+ tbaa_decorate_gcframe (user, visited);
122
+ }
123
+ }
124
+ }
125
+
126
+ void tbaa_decorate_gcframe (Instruction *inst)
127
+ {
128
+ std::set<Instruction*> visited;
129
+ tbaa_decorate_gcframe (inst, visited);
130
+ }
131
+
93
132
#ifndef NDEBUG // llvm assertions build
94
133
// gdb debugging code for inspecting the bb_uses map
95
134
void jl_dump_bb_uses (std::map<BasicBlock*, std::map<frame_register, liveness::id> > &bb_uses)
@@ -655,6 +694,7 @@ void allocate_frame()
655
694
// finalize all of the jlcall frames by replacing all of the frames with the appropriate gep(tempslot)
656
695
for (std::map<CallInst*, unsigned >::iterator frame = frame_offsets.begin (), framee = frame_offsets.end (); frame != framee; ++frame) {
657
696
CallInst *gcroot = frame->first ;
697
+ tbaa_decorate_gcframe (gcroot);
658
698
Value* offset[1 ] = {ConstantInt::get (T_int32, frame->second )};
659
699
GetElementPtrInst *gep = GetElementPtrInst::Create (LLVM37_param (NULL ) tempSlot, makeArrayRef (offset));
660
700
gep->insertAfter (last_gcframe_inst);
@@ -714,11 +754,13 @@ void allocate_frame()
714
754
}
715
755
}
716
756
#endif
757
+ tbaa_decorate_gcframe (callInst);
717
758
callInst->replaceAllUsesWith (argTempi);
718
759
argTempi->takeName (callInst);
719
760
callInst->eraseFromParent ();
720
761
// Initialize the slots for function variables to NULL
721
762
StoreInst *store = new StoreInst (V_null, argTempi);
763
+ store->setMetadata (llvm::LLVMContext::MD_tbaa, tbaa_gcframe);
722
764
store->insertAfter (argTempi);
723
765
last_gcframe_inst = store;
724
766
}
@@ -744,6 +786,7 @@ void allocate_frame()
744
786
Instruction *argTempi = GetElementPtrInst::Create (LLVM37_param (NULL ) tempSlot, ArrayRef<Value*>(ConstantInt::get (T_int32, i)));
745
787
argTempi->insertAfter (last_gcframe_inst);
746
788
StoreInst *store = new StoreInst (V_null, argTempi);
789
+ store->setMetadata (llvm::LLVMContext::MD_tbaa, tbaa_gcframe);
747
790
store->insertAfter (argTempi);
748
791
last_gcframe_inst = store;
749
792
}
@@ -763,10 +806,13 @@ void allocate_frame()
763
806
DebugLoc noDbg;
764
807
builder.SetCurrentDebugLocation (noDbg);
765
808
766
- builder.CreateStore (ConstantInt::get (T_size, (argSpaceSize + maxDepth) << 1 ),
767
- builder.CreateBitCast (builder.CreateConstGEP1_32 (gcframe, 0 ), T_size->getPointerTo ()));
768
- builder.CreateStore (builder.CreateLoad (builder.Insert (get_pgcstack (ptlsStates))),
769
- builder.CreatePointerCast (builder.CreateConstGEP1_32 (gcframe, 1 ), PointerType::get (T_ppjlvalue,0 )));
809
+ Instruction *inst =
810
+ builder.CreateStore (ConstantInt::get (T_size, (argSpaceSize + maxDepth) << 1 ),
811
+ builder.CreateBitCast (builder.CreateConstGEP1_32 (gcframe, 0 ), T_size->getPointerTo ()));
812
+ inst->setMetadata (llvm::LLVMContext::MD_tbaa, tbaa_gcframe);
813
+ inst = builder.CreateStore (builder.CreateLoad (builder.Insert (get_pgcstack (ptlsStates))),
814
+ builder.CreatePointerCast (builder.CreateConstGEP1_32 (gcframe, 1 ), PointerType::get (T_ppjlvalue,0 )));
815
+ inst->setMetadata (llvm::LLVMContext::MD_tbaa, tbaa_gcframe);
770
816
builder.CreateStore (gcframe, builder.Insert (get_pgcstack (ptlsStates)));
771
817
772
818
// Finish by emitting the gc pops before any return
@@ -775,9 +821,11 @@ void allocate_frame()
775
821
builder.SetInsertPoint (I->getTerminator ()); // set insert *before* Ret
776
822
Instruction *gcpop =
777
823
(Instruction*)builder.CreateConstGEP1_32 (gcframe, 1 );
778
- builder.CreateStore (builder.CreatePointerCast (builder.CreateLoad (gcpop),
779
- T_ppjlvalue),
780
- builder.Insert (get_pgcstack (ptlsStates)));
824
+ inst = builder.CreateLoad (gcpop);
825
+ inst->setMetadata (llvm::LLVMContext::MD_tbaa, tbaa_gcframe);
826
+ inst = builder.CreateStore (builder.CreatePointerCast (inst, T_ppjlvalue),
827
+ builder.Insert (get_pgcstack (ptlsStates)));
828
+ inst->setMetadata (llvm::LLVMContext::MD_tbaa, tbaa_gcframe);
781
829
}
782
830
}
783
831
}
@@ -791,8 +839,9 @@ void allocate_frame()
791
839
792
840
};
793
841
794
- void jl_codegen_finalize_temp_arg (CallInst *ptlsStates, Type *T_pjlvalue)
842
+ void jl_codegen_finalize_temp_arg (CallInst *ptlsStates, Type *T_pjlvalue,
843
+ MDNode *tbaa)
795
844
{
796
- JuliaGCAllocator allocator (ptlsStates, T_pjlvalue);
845
+ JuliaGCAllocator allocator (ptlsStates, T_pjlvalue, tbaa );
797
846
allocator.allocate_frame ();
798
847
}
0 commit comments