Handle the removal of the debug chain.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26729 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Laskey 2006-03-13 13:07:37 +00:00
parent 2e8a77ff42
commit f4321a3a43
9 changed files with 117 additions and 67 deletions

View File

@ -181,11 +181,11 @@ let Properties = [InstrNoMem] in {
//===------------------------ Debugger Intrinsics -------------------------===// //===------------------------ Debugger Intrinsics -------------------------===//
// //
def int_dbg_stoppoint : Intrinsic<[llvm_anchor_ty, llvm_anchor_ty, def int_dbg_stoppoint : Intrinsic<[llvm_void_ty,
llvm_uint_ty, llvm_uint_ty, llvm_uint_ty, llvm_uint_ty,
llvm_descriptor_ty]>; llvm_descriptor_ty]>;
def int_dbg_region_start : Intrinsic<[llvm_anchor_ty, llvm_anchor_ty]>; def int_dbg_region_start : Intrinsic<[llvm_void_ty]>;
def int_dbg_region_end : Intrinsic<[llvm_anchor_ty, llvm_anchor_ty]>; def int_dbg_region_end : Intrinsic<[llvm_void_ty]>;
def int_dbg_func_start : Intrinsic<[llvm_anchor_ty, llvm_descriptor_ty]>; def int_dbg_func_start : Intrinsic<[llvm_void_ty, llvm_descriptor_ty]>;
// dbg_declare, // Declare a local object // dbg_declare, // Declare a local object

View File

@ -1861,8 +1861,8 @@ void BytecodeReader::ParseFunctionBody(Function* F) {
if (!upgradedFunctions.empty()) { if (!upgradedFunctions.empty()) {
for (Function::iterator BI = F->begin(), BE = F->end(); BI != BE; ++BI) for (Function::iterator BI = F->begin(), BE = F->end(); BI != BE; ++BI)
for (BasicBlock::iterator II = BI->begin(), IE = BI->end(); for (BasicBlock::iterator II = BI->begin(), IE = BI->end();
II != IE; ++II) II != IE;)
if (CallInst* CI = dyn_cast<CallInst>(II)) { if (CallInst* CI = dyn_cast<CallInst>(II++)) {
std::map<Function*,Function*>::iterator FI = std::map<Function*,Function*>::iterator FI =
upgradedFunctions.find(CI->getCalledFunction()); upgradedFunctions.find(CI->getCalledFunction());
if (FI != upgradedFunctions.end()) if (FI != upgradedFunctions.end())

View File

@ -403,8 +403,6 @@ void DefaultIntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
case Intrinsic::dbg_region_start: case Intrinsic::dbg_region_start:
case Intrinsic::dbg_region_end: case Intrinsic::dbg_region_end:
case Intrinsic::dbg_func_start: case Intrinsic::dbg_func_start:
if (CI->getType() != Type::VoidTy)
CI->replaceAllUsesWith(Constant::getNullValue(CI->getType()));
break; // Simply strip out debugging intrinsics break; // Simply strip out debugging intrinsics
case Intrinsic::memcpy_i32: case Intrinsic::memcpy_i32:

View File

@ -966,19 +966,19 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
case Intrinsic::dbg_stoppoint: { case Intrinsic::dbg_stoppoint: {
MachineDebugInfo *DebugInfo = DAG.getMachineDebugInfo(); MachineDebugInfo *DebugInfo = DAG.getMachineDebugInfo();
if (DebugInfo && DebugInfo->Verify(I.getOperand(4))) { if (DebugInfo && DebugInfo->Verify(I.getOperand(3))) {
std::vector<SDOperand> Ops; std::vector<SDOperand> Ops;
// Input Chain // Input Chain
Ops.push_back(getRoot()); Ops.push_back(getRoot());
// line number // line number
Ops.push_back(getValue(I.getOperand(2))); Ops.push_back(getValue(I.getOperand(1)));
// column // column
Ops.push_back(getValue(I.getOperand(3))); Ops.push_back(getValue(I.getOperand(2)));
DebugInfoDesc *DD = DebugInfo->getDescFor(I.getOperand(4)); DebugInfoDesc *DD = DebugInfo->getDescFor(I.getOperand(3));
assert(DD && "Not a debug information descriptor"); assert(DD && "Not a debug information descriptor");
CompileUnitDesc *CompileUnit = dyn_cast<CompileUnitDesc>(DD); CompileUnitDesc *CompileUnit = dyn_cast<CompileUnitDesc>(DD);
assert(CompileUnit && "Not a compile unit"); assert(CompileUnit && "Not a compile unit");

View File

@ -63,11 +63,11 @@ static const GlobalVariable *getNextStopPoint(const Value *V, unsigned &LineNo,
if (F->getIntrinsicID() == Intrinsic::dbg_stoppoint) { if (F->getIntrinsicID() == Intrinsic::dbg_stoppoint) {
unsigned CurLineNo = ~0, CurColNo = ~0; unsigned CurLineNo = ~0, CurColNo = ~0;
const GlobalVariable *CurDesc = 0; const GlobalVariable *CurDesc = 0;
if (const ConstantInt *C = dyn_cast<ConstantInt>(CI->getOperand(2))) if (const ConstantInt *C = dyn_cast<ConstantInt>(CI->getOperand(1)))
CurLineNo = C->getRawValue(); CurLineNo = C->getRawValue();
if (const ConstantInt *C = dyn_cast<ConstantInt>(CI->getOperand(3))) if (const ConstantInt *C = dyn_cast<ConstantInt>(CI->getOperand(2)))
CurColNo = C->getRawValue(); CurColNo = C->getRawValue();
const Value *Op = CI->getOperand(4); const Value *Op = CI->getOperand(3);
if ((CurDesc = dyn_cast<GlobalVariable>(Op)) && if ((CurDesc = dyn_cast<GlobalVariable>(Op)) &&
(LineNo < LastLineNo || (LineNo < LastLineNo ||

View File

@ -1691,8 +1691,8 @@ void CWriter::visitCallInst(CallInst &I) {
case Intrinsic::dbg_stoppoint: { case Intrinsic::dbg_stoppoint: {
// If we use writeOperand directly we get a "u" suffix which is rejected // If we use writeOperand directly we get a "u" suffix which is rejected
// by gcc. // by gcc.
ConstantUInt *SI = cast<ConstantUInt>(I.getOperand(2)); ConstantUInt *SI = cast<ConstantUInt>(I.getOperand(1));
GlobalVariable *GV = cast<GlobalVariable>(I.getOperand(4)); GlobalVariable *GV = cast<GlobalVariable>(I.getOperand(3));
ConstantStruct *CS = cast<ConstantStruct>(GV->getInitializer()); ConstantStruct *CS = cast<ConstantStruct>(GV->getInitializer());
std::string FileName = CS->getOperand(4)->getStringValue(); std::string FileName = CS->getOperand(4)->getStringValue();
std::string Directory = CS->getOperand(5)->getStringValue(); std::string Directory = CS->getOperand(5)->getStringValue();

View File

@ -1691,8 +1691,8 @@ void CWriter::visitCallInst(CallInst &I) {
case Intrinsic::dbg_stoppoint: { case Intrinsic::dbg_stoppoint: {
// If we use writeOperand directly we get a "u" suffix which is rejected // If we use writeOperand directly we get a "u" suffix which is rejected
// by gcc. // by gcc.
ConstantUInt *SI = cast<ConstantUInt>(I.getOperand(2)); ConstantUInt *SI = cast<ConstantUInt>(I.getOperand(1));
GlobalVariable *GV = cast<GlobalVariable>(I.getOperand(4)); GlobalVariable *GV = cast<GlobalVariable>(I.getOperand(3));
ConstantStruct *CS = cast<ConstantStruct>(GV->getInitializer()); ConstantStruct *CS = cast<ConstantStruct>(GV->getInitializer());
std::string FileName = CS->getOperand(4)->getStringValue(); std::string FileName = CS->getOperand(4)->getStringValue();
std::string Directory = CS->getOperand(5)->getStringValue(); std::string Directory = CS->getOperand(5)->getStringValue();

View File

@ -116,7 +116,7 @@ bool StripSymbols::runOnModule(Module &M) {
Value *RV = UndefValue::get(StopPoint->getFunctionType()->getReturnType()); Value *RV = UndefValue::get(StopPoint->getFunctionType()->getReturnType());
while (!StopPoint->use_empty()) { while (!StopPoint->use_empty()) {
CallInst *CI = cast<CallInst>(StopPoint->use_back()); CallInst *CI = cast<CallInst>(StopPoint->use_back());
Value *Arg = CI->getOperand(4); Value *Arg = CI->getOperand(3);
CI->replaceAllUsesWith(RV); CI->replaceAllUsesWith(RV);
CI->eraseFromParent(); CI->eraseFromParent();
if (Arg->use_empty()) if (Arg->use_empty())

View File

@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Assembly/AutoUpgrade.h" #include "llvm/Assembly/AutoUpgrade.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h" #include "llvm/DerivedTypes.h"
#include "llvm/Function.h" #include "llvm/Function.h"
#include "llvm/Module.h" #include "llvm/Module.h"
@ -73,6 +74,31 @@ static Function *getUpgradedIntrinsic(Function *F) {
if (Name == "llvm.ctpop" || Name == "llvm.ctlz" || Name == "llvm.cttz") if (Name == "llvm.ctpop" || Name == "llvm.ctlz" || Name == "llvm.cttz")
return getUpgradedUnaryFn(F); return getUpgradedUnaryFn(F);
break; break;
case 'd':
if (Name == "llvm.dbg.stoppoint") {
if (F->getReturnType() != Type::VoidTy) {
return M->getOrInsertFunction(Name, Type::VoidTy,
Type::UIntTy,
Type::UIntTy,
F->getFunctionType()->getParamType(3),
NULL);
}
} else if (Name == "llvm.dbg.func.start") {
if (F->getReturnType() != Type::VoidTy) {
return M->getOrInsertFunction(Name, Type::VoidTy,
F->getFunctionType()->getParamType(0),
NULL);
}
} else if (Name == "llvm.dbg.region.start") {
if (F->getReturnType() != Type::VoidTy) {
return M->getOrInsertFunction(Name, Type::VoidTy, NULL);
}
} else if (Name == "llvm.dbg.region.end") {
if (F->getReturnType() != Type::VoidTy) {
return M->getOrInsertFunction(Name, Type::VoidTy, NULL);
}
}
break;
case 'i': case 'i':
if (Name == "llvm.isunordered" && F->arg_begin() != F->arg_end()) { if (Name == "llvm.isunordered" && F->arg_begin() != F->arg_end()) {
if (F->arg_begin()->getType() == Type::FloatTy) if (F->arg_begin()->getType() == Type::FloatTy)
@ -106,6 +132,29 @@ static Function *getUpgradedIntrinsic(Function *F) {
return 0; return 0;
} }
// Occasionally upgraded function call site arguments need to be permutated to
// some new order. The result of getArgumentPermutation is an array of size
// F->getFunctionType()getNumParams() indicating the new operand order. A value
// of zero in the array indicates replacing with UndefValue for the arg type.
// NULL is returned if there is no permutation. It's assumed that the function
// name is in the form "llvm.?????"
static unsigned *getArgumentPermutation(Function* F) {
// Get the Function's name.
const std::string& Name = F->getName();
switch (Name[5]) {
case 'd':
if (Name == "llvm.dbg.stoppoint") {
static unsigned Permutation[] = { 2, 3, 4 };
assert(F->getFunctionType()->getNumParams() ==
(sizeof(Permutation) / sizeof(unsigned)) &&
"Permutation is wrong length");
return Permutation;
}
break;
}
return NULL;
}
// UpgradeIntrinsicFunction - Convert overloaded intrinsic function names to // UpgradeIntrinsicFunction - Convert overloaded intrinsic function names to
// their non-overloaded variants by appending the appropriate suffix based on // their non-overloaded variants by appending the appropriate suffix based on
// the argument types. // the argument types.
@ -157,72 +206,75 @@ Instruction* llvm::MakeUpgradedCall(Function *F,
return result; return result;
} }
// UpgradeIntrinsicCall - In the BC reader, change a call to some intrinsic to // UpgradeIntrinsicCall - In the BC reader, change a call to an intrinsic to be
// be a called to the specified intrinsic. We expect the callees to have the // a call to an upgraded intrinsic. We may have to permute the order or promote
// same number of arguments, but their types may be different. // some arguments with a cast.
void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Function *F = CI->getCalledFunction(); Function *F = CI->getCalledFunction();
const FunctionType *NewFnTy = NewFn->getFunctionType(); const FunctionType *NewFnTy = NewFn->getFunctionType();
std::vector<Value*> Oprnds; std::vector<Value*> Oprnds;
for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i) {
Value *V = CI->getOperand(i); unsigned *Permutation = getArgumentPermutation(NewFn);
if (V->getType() != NewFnTy->getParamType(i-1)) unsigned N = NewFnTy->getNumParams();
V = new CastInst(V, NewFnTy->getParamType(i-1), V->getName(), CI);
if (Permutation) {
for (unsigned i = 0; i != N; ++i) {
unsigned p = Permutation[i];
if (p) {
Value *V = CI->getOperand(p);
if (V->getType() != NewFnTy->getParamType(i))
V = new CastInst(V, NewFnTy->getParamType(i), V->getName(), CI);
Oprnds.push_back(V);
} else
Oprnds.push_back(UndefValue::get(NewFnTy->getParamType(i)));
}
} else {
assert(N == (CI->getNumOperands() - 1) &&
"Upgraded function needs permutation");
for (unsigned i = 0; i != N; ++i) {
Value *V = CI->getOperand(i + 1);
if (V->getType() != NewFnTy->getParamType(i))
V = new CastInst(V, NewFnTy->getParamType(i), V->getName(), CI);
Oprnds.push_back(V); Oprnds.push_back(V);
} }
CallInst *NewCI = new CallInst(NewFn, Oprnds, CI->getName(), CI); }
bool NewIsVoid = NewFn->getReturnType() == Type::VoidTy;
CallInst *NewCI = new CallInst(NewFn, Oprnds,
NewIsVoid ? "" : CI->getName(),
CI);
NewCI->setTailCall(CI->isTailCall()); NewCI->setTailCall(CI->isTailCall());
NewCI->setCallingConv(CI->getCallingConv()); NewCI->setCallingConv(CI->getCallingConv());
if (!CI->use_empty()) { if (!CI->use_empty()) {
if (NewIsVoid) {
CI->replaceAllUsesWith(UndefValue::get(CI->getType()));
} else {
Instruction *RetVal = NewCI; Instruction *RetVal = NewCI;
if (F->getReturnType() != NewFn->getReturnType()) { if (F->getReturnType() != NewFn->getReturnType()) {
RetVal = new CastInst(NewCI, NewFn->getReturnType(), RetVal = new CastInst(NewCI, NewFn->getReturnType(),
NewCI->getName(), CI); NewCI->getName(), CI);
NewCI->moveBefore(RetVal); NewCI->moveBefore(RetVal);
} }
CI->replaceAllUsesWith(RetVal); CI->replaceAllUsesWith(RetVal);
} }
}
CI->eraseFromParent(); CI->eraseFromParent();
} }
bool llvm::UpgradeCallsToIntrinsic(Function* F) { bool llvm::UpgradeCallsToIntrinsic(Function* F) {
if (Function* newF = UpgradeIntrinsicFunction(F)) { if (Function* NewFn = UpgradeIntrinsicFunction(F)) {
for (Value::use_iterator UI = F->use_begin(), UE = F->use_end(); for (Value::use_iterator UI = F->use_begin(), UE = F->use_end();
UI != UE; ) { UI != UE; ) {
if (CallInst* CI = dyn_cast<CallInst>(*UI++)) { if (CallInst* CI = dyn_cast<CallInst>(*UI++))
std::vector<Value*> Oprnds; UpgradeIntrinsicCall(CI, NewFn);
User::op_iterator OI = CI->op_begin();
++OI;
for (User::op_iterator OE = CI->op_end(); OI != OE; ++OI) {
const Type* opTy = OI->get()->getType();
if (opTy->isSigned()) {
Oprnds.push_back(
new CastInst(OI->get(),opTy->getUnsignedVersion(),
"autoupgrade_cast",CI));
} else {
Oprnds.push_back(*OI);
} }
} if (NewFn != F)
CallInst* newCI = new CallInst(newF, Oprnds,
CI->hasName() ? "autoupcall" : "", CI);
newCI->setTailCall(CI->isTailCall());
newCI->setCallingConv(CI->getCallingConv());
if (CI->use_empty()) {
// noop
} else if (CI->getType() != newCI->getType()) {
CastInst *final = new CastInst(newCI, CI->getType(),
"autoupgrade_uncast", newCI);
newCI->moveBefore(final);
CI->replaceAllUsesWith(final);
} else {
CI->replaceAllUsesWith(newCI);
}
CI->eraseFromParent();
}
}
if (newF != F)
F->eraseFromParent(); F->eraseFromParent();
return true; return true;
} }