mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-24 15:12:36 +00:00
Use getIntrinsicID instead of looking up intrinsic prototypes. Also
fixes a bug with indirect calls. (Test case will be included with ocaml collector patch.) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45316 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
860b25a611
commit
a6c9925087
@ -35,10 +35,6 @@ namespace {
|
|||||||
/// directed by the Collector. It also performs automatic root initialization
|
/// directed by the Collector. It also performs automatic root initialization
|
||||||
/// and custom intrinsic lowering.
|
/// and custom intrinsic lowering.
|
||||||
class VISIBILITY_HIDDEN LowerIntrinsics : public FunctionPass {
|
class VISIBILITY_HIDDEN LowerIntrinsics : public FunctionPass {
|
||||||
/// GCRootInt, GCReadInt, GCWriteInt - The function prototypes for the
|
|
||||||
/// llvm.gc* intrinsics.
|
|
||||||
Function *GCRootInt, *GCReadInt, *GCWriteInt;
|
|
||||||
|
|
||||||
static bool NeedsDefaultLoweringPass(const Collector &C);
|
static bool NeedsDefaultLoweringPass(const Collector &C);
|
||||||
static bool NeedsCustomLoweringPass(const Collector &C);
|
static bool NeedsCustomLoweringPass(const Collector &C);
|
||||||
static bool CouldBecomeSafePoint(Instruction *I);
|
static bool CouldBecomeSafePoint(Instruction *I);
|
||||||
@ -138,8 +134,7 @@ FunctionPass *llvm::createGCLoweringPass() {
|
|||||||
char LowerIntrinsics::ID = 0;
|
char LowerIntrinsics::ID = 0;
|
||||||
|
|
||||||
LowerIntrinsics::LowerIntrinsics()
|
LowerIntrinsics::LowerIntrinsics()
|
||||||
: FunctionPass((intptr_t)&ID),
|
: FunctionPass((intptr_t)&ID) {}
|
||||||
GCRootInt(0), GCReadInt(0), GCWriteInt(0) {}
|
|
||||||
|
|
||||||
const char *LowerIntrinsics::getPassName() const {
|
const char *LowerIntrinsics::getPassName() const {
|
||||||
return "Lower Garbage Collection Instructions";
|
return "Lower Garbage Collection Instructions";
|
||||||
@ -152,10 +147,6 @@ void LowerIntrinsics::getAnalysisUsage(AnalysisUsage &AU) const {
|
|||||||
|
|
||||||
/// doInitialization - If this module uses the GC intrinsics, find them now.
|
/// doInitialization - If this module uses the GC intrinsics, find them now.
|
||||||
bool LowerIntrinsics::doInitialization(Module &M) {
|
bool LowerIntrinsics::doInitialization(Module &M) {
|
||||||
GCReadInt = M.getFunction("llvm.gcread");
|
|
||||||
GCWriteInt = M.getFunction("llvm.gcwrite");
|
|
||||||
GCRootInt = M.getFunction("llvm.gcroot");
|
|
||||||
|
|
||||||
// FIXME: This is rather antisocial in the context of a JIT since it performs
|
// FIXME: This is rather antisocial in the context of a JIT since it performs
|
||||||
// work against the entire module. But this cannot be done at
|
// work against the entire module. But this cannot be done at
|
||||||
// runFunction time (initializeCustomLowering likely needs to change
|
// runFunction time (initializeCustomLowering likely needs to change
|
||||||
@ -277,25 +268,35 @@ bool LowerIntrinsics::PerformDefaultLowering(Function &F, Collector &Coll) {
|
|||||||
bool MadeChange = false;
|
bool MadeChange = false;
|
||||||
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
|
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
|
||||||
for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E;) {
|
for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E;) {
|
||||||
if (CallInst *CI = dyn_cast<CallInst>(II++)) {
|
if (IntrinsicInst *CI = dyn_cast<IntrinsicInst>(II++)) {
|
||||||
Function *F = CI->getCalledFunction();
|
Function *F = CI->getCalledFunction();
|
||||||
if (F == GCWriteInt && LowerWr) {
|
switch (F->getIntrinsicID()) {
|
||||||
// Replace a write barrier with a simple store.
|
case Intrinsic::gcwrite:
|
||||||
Value *St = new StoreInst(CI->getOperand(1), CI->getOperand(3), CI);
|
if (LowerWr) {
|
||||||
CI->replaceAllUsesWith(St);
|
// Replace a write barrier with a simple store.
|
||||||
CI->eraseFromParent();
|
Value *St = new StoreInst(CI->getOperand(1), CI->getOperand(3), CI);
|
||||||
} else if (F == GCReadInt && LowerRd) {
|
CI->replaceAllUsesWith(St);
|
||||||
// Replace a read barrier with a simple load.
|
CI->eraseFromParent();
|
||||||
Value *Ld = new LoadInst(CI->getOperand(2), "", CI);
|
}
|
||||||
Ld->takeName(CI);
|
break;
|
||||||
CI->replaceAllUsesWith(Ld);
|
case Intrinsic::gcread:
|
||||||
CI->eraseFromParent();
|
if (LowerRd) {
|
||||||
} else if (F == GCRootInt && InitRoots) {
|
// Replace a read barrier with a simple load.
|
||||||
// Initialize the GC root, but do not delete the intrinsic. The
|
Value *Ld = new LoadInst(CI->getOperand(2), "", CI);
|
||||||
// backend needs the intrinsic to flag the stack slot.
|
Ld->takeName(CI);
|
||||||
Roots.push_back(cast<AllocaInst>(
|
CI->replaceAllUsesWith(Ld);
|
||||||
IntrinsicInst::StripPointerCasts(CI->getOperand(1))));
|
CI->eraseFromParent();
|
||||||
} else {
|
}
|
||||||
|
break;
|
||||||
|
case Intrinsic::gcroot:
|
||||||
|
if (InitRoots) {
|
||||||
|
// Initialize the GC root, but do not delete the intrinsic. The
|
||||||
|
// backend needs the intrinsic to flag the stack slot.
|
||||||
|
Roots.push_back(cast<AllocaInst>(
|
||||||
|
IntrinsicInst::StripPointerCasts(CI->getOperand(1))));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user