Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Temp commit

  • Loading branch information...
commit b2280890de6cffeeb6e83a964e253509961c0391 1 parent 68e3324
@pcwalton pcwalton authored erickt committed
View
6 include/llvm/Target/Target.td
@@ -749,6 +749,12 @@ def COPY : Instruction {
let neverHasSideEffects = 1;
let isAsCheapAsAMove = 1;
}
+def GC_REG_ROOT : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins unknown:$src, i32imm:$addrspace);
+ let AsmString = "GC_REG_ROOT";
+ let isAsCheapAsAMove = 1;
+}
def BUNDLE : Instruction {
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
View
12 lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -699,6 +699,18 @@ void AsmPrinter::EmitFunctionBody() {
case TargetOpcode::KILL:
if (isVerbose()) emitKill(II, *this);
break;
+ case TargetOpcode::GC_REG_ROOT: {
+ if (!isVerbose())
+ break;
+ SmallString<128> Str;
+ raw_svector_ostream OS(Str);
+ OS << '\t' << MAI->getCommentString() << "GC_REG_ROOT ";
+ if (II->getOperand(0).isReg())
+ OS << TM.getRegisterInfo()->getName(II->getOperand(0).getReg());
+ OS << ", " << II->getOperand(1).getImm();
+ OutStreamer.EmitRawText(OS.str());
+ break;
+ }
default:
if (!TM.hasMCUseLoc())
MCLineEntry::Make(&OutStreamer, getCurrentSection());
View
79 lib/CodeGen/GCStrategy.cpp
@@ -47,6 +47,7 @@ namespace {
bool PerformDefaultLowering(Function &F, GCStrategy &Coll);
static bool InsertRootInitializers(Function &F,
AllocaInst **Roots, unsigned Count);
+ void InsertGCRegisterRoots(Function &F, GCStrategy &S);
public:
static char ID;
@@ -153,7 +154,7 @@ const char *LowerIntrinsics::getPassName() const {
void LowerIntrinsics::getAnalysisUsage(AnalysisUsage &AU) const {
FunctionPass::getAnalysisUsage(AU);
AU.addRequired<GCModuleInfo>();
- AU.addPreserved<DominatorTree>();
+ AU.addRequired<DominatorTree>();
}
/// doInitialization - If this module uses the GC intrinsics, find them now.
@@ -277,7 +278,83 @@ bool LowerIntrinsics::runOnFunction(Function &F) {
return MadeChange;
}
+void LowerIntrinsics::InsertGCRegisterRoots(Function &F, GCStrategy &S) {
+ DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>();
+ if (!DT)
+ return;
+
+ // Gather up all of the GC roots in the function.
+ SmallVector<Instruction *, 8> GCRoots;
+ for (Function::iterator BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI) {
+ for (BasicBlock::iterator II = BBI->begin(),
+ IE = BBI->end(); II != IE; ++II) {
+ if (isa<PointerType>(II->getType()) &&
+ cast<PointerType>(II->getType())->getAddressSpace() != 0) {
+ GCRoots.push_back(&*II);
+ }
+ }
+ }
+
+ // Now insert calls to llvm.gcregroot after calls.
+ Function *GCRegRootFn = Intrinsic::getDeclaration(F.getParent(),
+ Intrinsic::gcregroot);
+ Type *PtrTy = Type::getInt8PtrTy(F.getParent()->getContext());
+ for (Function::iterator BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI) {
+ for (BasicBlock::iterator II = BBI->begin(),
+ IE = BBI->end(); II != IE; ++II) {
+ if (!isa<CallInst>(&*II) && !isa<InvokeInst>(&*II))
+ continue;
+
+ // Skip intrinsic calls. This prevents infinite loops.
+ if (isa<CallInst>(&*II)) {
+ Function *Fn = cast<CallInst>(&*II)->getCalledFunction();
+ if (Fn && Fn->isIntrinsic())
+ continue;
+ }
+
+ // Find all the live GC roots, and create gcregroot intrinsics for them.
+ //
+ // FIXME: Only considers dominance right now...
+ SmallVector<Instruction *, 8> GeneratedInsts;
+ for (SmallVector<Instruction *, 8>::iterator RI = GCRoots.begin(),
+ RE = GCRoots.end();
+ RI != RE; ++RI) {
+ if (!DT->dominates(*RI, &*II))
+ continue;
+
+ // Cast the value to an i8* to make a type-compatible intrinsic call.
+ Instruction *GCRegRootArg = new BitCastInst(*RI, PtrTy);
+ GeneratedInsts.push_back(GCRegRootArg);
+
+ // Create an intrinsic call.
+ Value *Args[1];
+ Args[0] = GCRegRootArg;
+ GeneratedInsts.push_back(CallInst::Create(GCRegRootFn, Args));
+ }
+
+ // Insert the gcregroot intrinsic calls after the call.
+ if (isa<CallInst>(&*II)) {
+ for (SmallVector<Instruction *, 8>::reverse_iterator CII =
+ GeneratedInsts.rbegin(), CIE = GeneratedInsts.rend();
+ CII != CIE; ++CII) {
+ (*CII)->insertAfter(&*II);
+ }
+ } else { // Invoke instruction
+ BasicBlock *NormalDest = cast<InvokeInst>(&*II)->getNormalDest();
+ Instruction &InsertPt = NormalDest->front();
+ for (SmallVector<Instruction *, 8>::iterator CII =
+ GeneratedInsts.begin(), CIE = GeneratedInsts.end();
+ CII != CIE; ++CII) {
+ (*CII)->insertBefore(&InsertPt);
+ }
+ }
+ }
+ }
+}
+
bool LowerIntrinsics::PerformDefaultLowering(Function &F, GCStrategy &S) {
+ InsertGCRegisterRoots(F, S);
+
bool LowerWr = !S.customWriteBarrier();
bool LowerRd = !S.customReadBarrier();
bool InitRoots = S.initializeRoots();
View
4 lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -676,7 +676,9 @@ bool FastISel::SelectCall(const User *I) {
return true;
}
case Intrinsic::gcregroot: {
- Value *Arg = Call->getArgOperand(1);
+ Value *Arg = Call->getArgOperand(0);
+ printf("### Arg operand:\n");
+ Arg->dump();
unsigned ResultReg = getRegForValue(Arg);
if (ResultReg == 0)
return false;
View
1  utils/TableGen/CodeGenTarget.cpp
@@ -306,6 +306,7 @@ void CodeGenTarget::ComputeInstrsByEnum() const {
"DBG_VALUE",
"REG_SEQUENCE",
"COPY",
+ "GC_REG_ROOT",
"BUNDLE",
"LIFETIME_START",
"LIFETIME_END",
Please sign in to comment.
Something went wrong with that request. Please try again.