/// This function strips all debug info intrinsics, except for llvm.dbg.declare. /// If an llvm.dbg.declare intrinsic is invalid, then this function simply /// strips that use. void llvm::CheckDebugInfoIntrinsics(Module *M) { if (Function *FuncStart = M->getFunction("llvm.dbg.func.start")) { while (!FuncStart->use_empty()) cast<CallInst>(FuncStart->use_back())->eraseFromParent(); FuncStart->eraseFromParent(); } if (Function *StopPoint = M->getFunction("llvm.dbg.stoppoint")) { while (!StopPoint->use_empty()) cast<CallInst>(StopPoint->use_back())->eraseFromParent(); StopPoint->eraseFromParent(); } if (Function *RegionStart = M->getFunction("llvm.dbg.region.start")) { while (!RegionStart->use_empty()) cast<CallInst>(RegionStart->use_back())->eraseFromParent(); RegionStart->eraseFromParent(); } if (Function *RegionEnd = M->getFunction("llvm.dbg.region.end")) { while (!RegionEnd->use_empty()) cast<CallInst>(RegionEnd->use_back())->eraseFromParent(); RegionEnd->eraseFromParent(); } if (Function *Declare = M->getFunction("llvm.dbg.declare")) { if (!Declare->use_empty()) { DbgDeclareInst *DDI = cast<DbgDeclareInst>(Declare->use_back()); if (!isa<MDNode>(DDI->getArgOperand(0)) || !isa<MDNode>(DDI->getArgOperand(1))) { while (!Declare->use_empty()) { CallInst *CI = cast<CallInst>(Declare->use_back()); CI->eraseFromParent(); } Declare->eraseFromParent(); } } } }
bool FastISel::SelectCall(User *I) { Function *F = cast<CallInst>(I)->getCalledFunction(); if (!F) return false; unsigned IID = F->getIntrinsicID(); switch (IID) { default: break; case Intrinsic::dbg_stoppoint: case Intrinsic::dbg_region_start: case Intrinsic::dbg_region_end: case Intrinsic::dbg_func_start: // FIXME - Remove this instructions once the dust settles. return true; case Intrinsic::dbg_declare: { DbgDeclareInst *DI = cast<DbgDeclareInst>(I); if (!isValidDebugInfoIntrinsic(*DI, CodeGenOpt::None) || !DW || !DW->ShouldEmitDwarfDebug()) return true; Value *Address = DI->getAddress(); if (BitCastInst *BCI = dyn_cast<BitCastInst>(Address)) Address = BCI->getOperand(0); AllocaInst *AI = dyn_cast<AllocaInst>(Address); // Don't handle byval struct arguments or VLAs, for example. if (!AI) break; DenseMap<const AllocaInst*, int>::iterator SI = StaticAllocaMap.find(AI); if (SI == StaticAllocaMap.end()) break; // VLAs. int FI = SI->second; if (MMI) { MetadataContext &TheMetadata = DI->getParent()->getContext().getMetadata(); unsigned MDDbgKind = TheMetadata.getMDKind("dbg"); MDNode *Dbg = TheMetadata.getMD(MDDbgKind, DI); MMI->setVariableDbgInfo(DI->getVariable(), FI, Dbg); } return true; } case Intrinsic::eh_exception: { EVT VT = TLI.getValueType(I->getType()); switch (TLI.getOperationAction(ISD::EXCEPTIONADDR, VT)) { default: break; case TargetLowering::Expand: { assert(MBB->isLandingPad() && "Call to eh.exception not in landing pad!"); unsigned Reg = TLI.getExceptionAddressRegister(); const TargetRegisterClass *RC = TLI.getRegClassFor(VT); unsigned ResultReg = createResultReg(RC); bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, Reg, RC, RC); assert(InsertedCopy && "Can't copy address registers!"); InsertedCopy = InsertedCopy; UpdateValueMap(I, ResultReg); return true; } } break; } case Intrinsic::eh_selector: { EVT VT = TLI.getValueType(I->getType()); switch (TLI.getOperationAction(ISD::EHSELECTION, VT)) { default: break; case TargetLowering::Expand: { if (MMI) { if (MBB->isLandingPad()) AddCatchInfo(*cast<CallInst>(I), MMI, MBB); else { #ifndef NDEBUG CatchInfoLost.insert(cast<CallInst>(I)); #endif // FIXME: Mark exception selector register as live in. Hack for PR1508. unsigned Reg = TLI.getExceptionSelectorRegister(); if (Reg) MBB->addLiveIn(Reg); } unsigned Reg = TLI.getExceptionSelectorRegister(); EVT SrcVT = TLI.getPointerTy(); const TargetRegisterClass *RC = TLI.getRegClassFor(SrcVT); unsigned ResultReg = createResultReg(RC); bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, Reg, RC, RC); assert(InsertedCopy && "Can't copy address registers!"); InsertedCopy = InsertedCopy; // Cast the register to the type of the selector. if (SrcVT.bitsGT(MVT::i32)) ResultReg = FastEmit_r(SrcVT.getSimpleVT(), MVT::i32, ISD::TRUNCATE, ResultReg); else if (SrcVT.bitsLT(MVT::i32)) ResultReg = FastEmit_r(SrcVT.getSimpleVT(), MVT::i32, ISD::SIGN_EXTEND, ResultReg); if (ResultReg == 0) // Unhandled operand. Halt "fast" selection and bail. return false; UpdateValueMap(I, ResultReg); } else { unsigned ResultReg = getRegForValue(Constant::getNullValue(I->getType())); UpdateValueMap(I, ResultReg); } return true; } } break; } } return false; }
/// isValidDebugInfoIntrinsic - Return true if DI is a valid debug /// info intrinsic. bool isValidDebugInfoIntrinsic(DbgDeclareInst &DI, CodeGenOpt::Level OptLev) { return DIDescriptor::ValidDebugInfo(DI.getVariable(), OptLev); }