Skip to content

Commit

Permalink
Refactor LateLowerGCFrame. We do not need inheritance.
Browse files Browse the repository at this point in the history
  • Loading branch information
qinsoon committed Nov 28, 2024
1 parent 0fb147c commit 483cb93
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 70 deletions.
17 changes: 10 additions & 7 deletions src/llvm-gc-interface-passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,7 @@ struct LateLowerGCFrame: private JuliaPassContext {
LateLowerGCFrame(function_ref<DominatorTree &()> GetDT) : GetDT(GetDT) {}

public:
int need_gc_preserve_hook;
virtual bool runOnFunction(Function &F, bool *CFGModified = nullptr);
bool runOnFunction(Function &F, bool *CFGModified = nullptr);

private:
CallInst *pgcstack;
Expand Down Expand Up @@ -362,6 +361,7 @@ struct LateLowerGCFrame: private JuliaPassContext {
void PlaceGCFrameStores(State &S, unsigned MinColorRoot, ArrayRef<int> Colors, Value *GCFrame);
void PlaceRootsAndUpdateCalls(SmallVectorImpl<int> &Colors, State &S, std::map<Value *, std::pair<int, int>>);
void CleanupWriteBarriers(Function &F, State *S, const SmallVector<CallInst*, 0> &WriteBarriers, bool *CFGModified);
void cleanupGCPreserve(Function &F, CallInst *CI, Value *callee, Type *T_size);
bool CleanupIR(Function &F, State *S, bool *CFGModified);
void NoteUseChain(State &S, BBState &BBS, User *TheUser);
SmallVector<int, 1> GetPHIRefinements(PHINode *phi, State &S);
Expand All @@ -374,11 +374,6 @@ struct LateLowerGCFrame: private JuliaPassContext {
#endif
};

struct LateLowerGCFrameCustom: public LateLowerGCFrame {
public:
bool runOnFunction(Function &F, bool *CFGModified = nullptr) override;
};

// The final GC lowering pass. This pass lowers platform-agnostic GC
// intrinsics to platform-dependent instruction sequences. The
// intrinsics it targets are those produced by the late GC frame
Expand Down Expand Up @@ -434,4 +429,12 @@ struct FinalLowerGC: private JuliaPassContext {
#endif
};

inline bool isSpecialPtr(Type *Ty) {
PointerType *PTy = dyn_cast<PointerType>(Ty);
if (!PTy)
return false;
unsigned AS = PTy->getAddressSpace();
return AddressSpace::FirstSpecial <= AS && AS <= AddressSpace::LastSpecial;
}

#endif // LLVM_GC_PASSES_H
2 changes: 1 addition & 1 deletion src/llvm-julia-passes.inc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ MODULE_PASS("LowerPTLSPass", LowerPTLSPass, LowerPTLSPass())
//Function passes
#ifdef FUNCTION_PASS
FUNCTION_PASS("DemoteFloat16", DemoteFloat16Pass, DemoteFloat16Pass())
FUNCTION_PASS("LateLowerGCFrameCustom", LateLowerGCPass, LateLowerGCPass())
FUNCTION_PASS("LateLowerGCFrame", LateLowerGCPass, LateLowerGCPass())
FUNCTION_PASS("AllocOpt", AllocOptPass, AllocOptPass())
FUNCTION_PASS("PropagateJuliaAddrspaces", PropagateJuliaAddrspacesPass, PropagateJuliaAddrspacesPass())
FUNCTION_PASS("LowerExcHandlers", LowerExcHandlersPass, LowerExcHandlersPass())
Expand Down
47 changes: 44 additions & 3 deletions src/llvm-late-gc-lowering-mmtk.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,47 @@
#include "llvm-gc-interface-passes.h"

bool LateLowerGCFrameCustom::runOnFunction(Function &F, bool *CFGModified) {
need_gc_preserve_hook = 1;
return LateLowerGCFrame::runOnFunction(F, CFGModified);
void LateLowerGCFrame::cleanupGCPreserve(Function &F, CallInst *CI, Value *callee, Type *T_size) {
if (callee == gc_preserve_begin_func) {
// Initialize an IR builder.
IRBuilder<> builder(CI);

builder.SetCurrentDebugLocation(CI->getDebugLoc());
size_t nargs = 0;
State S2(F);

std::vector<Value*> args;
for (Use &U : CI->args()) {
Value *V = U;
if (isa<Constant>(V))
continue;
if (isa<PointerType>(V->getType())) {
if (isSpecialPtr(V->getType())) {
int Num = Number(S2, V);
if (Num >= 0) {
nargs++;
Value *Val = GetPtrForNumber(S2, Num, CI);
args.push_back(Val);
}
}
} else {
auto Nums = NumberAll(S2, V);
for (int Num : Nums) {
if (Num < 0)
continue;
Value *Val = GetPtrForNumber(S2, Num, CI);
args.push_back(Val);
nargs++;
}
}
}
args.insert(args.begin(), ConstantInt::get(T_size, nargs));

ArrayRef<Value*> args_llvm = ArrayRef<Value*>(args);
builder.CreateCall(getOrDeclare(jl_well_known::GCPreserveBeginHook), args_llvm );
} else if (callee == gc_preserve_end_func) {
// Initialize an IR builder.
IRBuilder<> builder(CI);
builder.SetCurrentDebugLocation(CI->getDebugLoc());
builder.CreateCall(getOrDeclare(jl_well_known::GCPreserveEndHook), {});
}
}
5 changes: 2 additions & 3 deletions src/llvm-late-gc-lowering-stock.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include "llvm-gc-interface-passes.h"

bool LateLowerGCFrameCustom::runOnFunction(Function &F, bool *CFGModified) {
need_gc_preserve_hook = 0;
return LateLowerGCFrame::runOnFunction(F, CFGModified);
void LateLowerGCFrame::cleanupGCPreserve(Function &F, CallInst *CI, Value *callee, Type *T_size) {
// Do nothing for the stock GC
}
60 changes: 4 additions & 56 deletions src/llvm-late-gc-lowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,6 @@ static bool isTrackedValue(Value *V) {
return PT && PT->getAddressSpace() == AddressSpace::Tracked;
}

static bool isSpecialPtr(Type *Ty) {
PointerType *PTy = dyn_cast<PointerType>(Ty);
if (!PTy)
return false;
unsigned AS = PTy->getAddressSpace();
return AddressSpace::FirstSpecial <= AS && AS <= AddressSpace::LastSpecial;
}

// return how many Special pointers are in T (count > 0),
// and if there is anything else in T (all == false)
CountTrackedPointers::CountTrackedPointers(Type *T, bool ignore_loaded) {
Expand Down Expand Up @@ -2089,55 +2081,11 @@ bool LateLowerGCFrame::CleanupIR(Function &F, State *S, bool *CFGModified) {
continue;
}
Value *callee = CI->getCalledOperand();
if (callee && (callee == gc_flush_func || callee == gc_preserve_begin_func
if (callee && callee == gc_flush_func) {
/* No replacement */
} else if (callee && (callee == gc_preserve_begin_func
|| callee == gc_preserve_end_func)) {
/* Replace with a call to the hook functions */
if (need_gc_preserve_hook) {
if (callee == gc_preserve_begin_func) {
// Initialize an IR builder.
IRBuilder<> builder(CI);

builder.SetCurrentDebugLocation(CI->getDebugLoc());
size_t nargs = 0;
State S2(F);

std::vector<Value*> args;
for (Use &U : CI->args()) {
Value *V = U;
if (isa<Constant>(V))
continue;
if (isa<PointerType>(V->getType())) {
if (isSpecialPtr(V->getType())) {
int Num = Number(S2, V);
if (Num >= 0) {
nargs++;
Value *Val = GetPtrForNumber(S2, Num, CI);
args.push_back(Val);
}
}
} else {
auto Nums = NumberAll(S2, V);
for (int Num : Nums) {
if (Num < 0)
continue;
Value *Val = GetPtrForNumber(S2, Num, CI);
args.push_back(Val);
nargs++;
}
}
}
args.insert(args.begin(), ConstantInt::get(T_size, nargs));

ArrayRef<Value*> args_llvm = ArrayRef<Value*>(args);
builder.CreateCall(getOrDeclare(jl_well_known::GCPreserveBeginHook), args_llvm );
} else if (callee == gc_preserve_end_func) {
// Initialize an IR builder.
IRBuilder<> builder(CI);
builder.SetCurrentDebugLocation(CI->getDebugLoc());
builder.CreateCall(getOrDeclare(jl_well_known::GCPreserveEndHook), {});
}
}
// Otherwise no replacement
cleanupGCPreserve(F, CI, callee, T_size);
} else if (pointer_from_objref_func != nullptr && callee == pointer_from_objref_func) {
auto *obj = CI->getOperand(0);
auto *ASCI = new AddrSpaceCastInst(obj, CI->getType(), "", CI);
Expand Down

0 comments on commit 483cb93

Please sign in to comment.