mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
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:
parent
2e8a77ff42
commit
f4321a3a43
@ -181,11 +181,11 @@ let Properties = [InstrNoMem] in {
|
||||
//===------------------------ 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_descriptor_ty]>;
|
||||
def int_dbg_region_start : Intrinsic<[llvm_anchor_ty, llvm_anchor_ty]>;
|
||||
def int_dbg_region_end : Intrinsic<[llvm_anchor_ty, llvm_anchor_ty]>;
|
||||
def int_dbg_func_start : Intrinsic<[llvm_anchor_ty, llvm_descriptor_ty]>;
|
||||
def int_dbg_region_start : Intrinsic<[llvm_void_ty]>;
|
||||
def int_dbg_region_end : Intrinsic<[llvm_void_ty]>;
|
||||
def int_dbg_func_start : Intrinsic<[llvm_void_ty, llvm_descriptor_ty]>;
|
||||
// dbg_declare, // Declare a local object
|
||||
|
||||
|
@ -1861,8 +1861,8 @@ void BytecodeReader::ParseFunctionBody(Function* F) {
|
||||
if (!upgradedFunctions.empty()) {
|
||||
for (Function::iterator BI = F->begin(), BE = F->end(); BI != BE; ++BI)
|
||||
for (BasicBlock::iterator II = BI->begin(), IE = BI->end();
|
||||
II != IE; ++II)
|
||||
if (CallInst* CI = dyn_cast<CallInst>(II)) {
|
||||
II != IE;)
|
||||
if (CallInst* CI = dyn_cast<CallInst>(II++)) {
|
||||
std::map<Function*,Function*>::iterator FI =
|
||||
upgradedFunctions.find(CI->getCalledFunction());
|
||||
if (FI != upgradedFunctions.end())
|
||||
|
@ -403,8 +403,6 @@ void DefaultIntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
|
||||
case Intrinsic::dbg_region_start:
|
||||
case Intrinsic::dbg_region_end:
|
||||
case Intrinsic::dbg_func_start:
|
||||
if (CI->getType() != Type::VoidTy)
|
||||
CI->replaceAllUsesWith(Constant::getNullValue(CI->getType()));
|
||||
break; // Simply strip out debugging intrinsics
|
||||
|
||||
case Intrinsic::memcpy_i32:
|
||||
|
@ -966,19 +966,19 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
||||
|
||||
case Intrinsic::dbg_stoppoint: {
|
||||
MachineDebugInfo *DebugInfo = DAG.getMachineDebugInfo();
|
||||
if (DebugInfo && DebugInfo->Verify(I.getOperand(4))) {
|
||||
if (DebugInfo && DebugInfo->Verify(I.getOperand(3))) {
|
||||
std::vector<SDOperand> Ops;
|
||||
|
||||
// Input Chain
|
||||
Ops.push_back(getRoot());
|
||||
|
||||
// line number
|
||||
Ops.push_back(getValue(I.getOperand(2)));
|
||||
Ops.push_back(getValue(I.getOperand(1)));
|
||||
|
||||
// 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");
|
||||
CompileUnitDesc *CompileUnit = dyn_cast<CompileUnitDesc>(DD);
|
||||
assert(CompileUnit && "Not a compile unit");
|
||||
|
@ -63,11 +63,11 @@ static const GlobalVariable *getNextStopPoint(const Value *V, unsigned &LineNo,
|
||||
if (F->getIntrinsicID() == Intrinsic::dbg_stoppoint) {
|
||||
unsigned CurLineNo = ~0, CurColNo = ~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();
|
||||
if (const ConstantInt *C = dyn_cast<ConstantInt>(CI->getOperand(3)))
|
||||
if (const ConstantInt *C = dyn_cast<ConstantInt>(CI->getOperand(2)))
|
||||
CurColNo = C->getRawValue();
|
||||
const Value *Op = CI->getOperand(4);
|
||||
const Value *Op = CI->getOperand(3);
|
||||
|
||||
if ((CurDesc = dyn_cast<GlobalVariable>(Op)) &&
|
||||
(LineNo < LastLineNo ||
|
||||
|
@ -1691,8 +1691,8 @@ void CWriter::visitCallInst(CallInst &I) {
|
||||
case Intrinsic::dbg_stoppoint: {
|
||||
// If we use writeOperand directly we get a "u" suffix which is rejected
|
||||
// by gcc.
|
||||
ConstantUInt *SI = cast<ConstantUInt>(I.getOperand(2));
|
||||
GlobalVariable *GV = cast<GlobalVariable>(I.getOperand(4));
|
||||
ConstantUInt *SI = cast<ConstantUInt>(I.getOperand(1));
|
||||
GlobalVariable *GV = cast<GlobalVariable>(I.getOperand(3));
|
||||
ConstantStruct *CS = cast<ConstantStruct>(GV->getInitializer());
|
||||
std::string FileName = CS->getOperand(4)->getStringValue();
|
||||
std::string Directory = CS->getOperand(5)->getStringValue();
|
||||
|
@ -1691,8 +1691,8 @@ void CWriter::visitCallInst(CallInst &I) {
|
||||
case Intrinsic::dbg_stoppoint: {
|
||||
// If we use writeOperand directly we get a "u" suffix which is rejected
|
||||
// by gcc.
|
||||
ConstantUInt *SI = cast<ConstantUInt>(I.getOperand(2));
|
||||
GlobalVariable *GV = cast<GlobalVariable>(I.getOperand(4));
|
||||
ConstantUInt *SI = cast<ConstantUInt>(I.getOperand(1));
|
||||
GlobalVariable *GV = cast<GlobalVariable>(I.getOperand(3));
|
||||
ConstantStruct *CS = cast<ConstantStruct>(GV->getInitializer());
|
||||
std::string FileName = CS->getOperand(4)->getStringValue();
|
||||
std::string Directory = CS->getOperand(5)->getStringValue();
|
||||
|
@ -116,7 +116,7 @@ bool StripSymbols::runOnModule(Module &M) {
|
||||
Value *RV = UndefValue::get(StopPoint->getFunctionType()->getReturnType());
|
||||
while (!StopPoint->use_empty()) {
|
||||
CallInst *CI = cast<CallInst>(StopPoint->use_back());
|
||||
Value *Arg = CI->getOperand(4);
|
||||
Value *Arg = CI->getOperand(3);
|
||||
CI->replaceAllUsesWith(RV);
|
||||
CI->eraseFromParent();
|
||||
if (Arg->use_empty())
|
||||
|
@ -12,6 +12,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Assembly/AutoUpgrade.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/Module.h"
|
||||
@ -73,6 +74,31 @@ static Function *getUpgradedIntrinsic(Function *F) {
|
||||
if (Name == "llvm.ctpop" || Name == "llvm.ctlz" || Name == "llvm.cttz")
|
||||
return getUpgradedUnaryFn(F);
|
||||
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':
|
||||
if (Name == "llvm.isunordered" && F->arg_begin() != F->arg_end()) {
|
||||
if (F->arg_begin()->getType() == Type::FloatTy)
|
||||
@ -106,6 +132,29 @@ static Function *getUpgradedIntrinsic(Function *F) {
|
||||
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
|
||||
// their non-overloaded variants by appending the appropriate suffix based on
|
||||
// the argument types.
|
||||
@ -157,72 +206,75 @@ Instruction* llvm::MakeUpgradedCall(Function *F,
|
||||
return result;
|
||||
}
|
||||
|
||||
// UpgradeIntrinsicCall - In the BC reader, change a call to some intrinsic to
|
||||
// be a called to the specified intrinsic. We expect the callees to have the
|
||||
// same number of arguments, but their types may be different.
|
||||
// UpgradeIntrinsicCall - In the BC reader, change a call to an intrinsic to be
|
||||
// a call to an upgraded intrinsic. We may have to permute the order or promote
|
||||
// some arguments with a cast.
|
||||
void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
|
||||
Function *F = CI->getCalledFunction();
|
||||
|
||||
const FunctionType *NewFnTy = NewFn->getFunctionType();
|
||||
std::vector<Value*> Oprnds;
|
||||
for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i) {
|
||||
Value *V = CI->getOperand(i);
|
||||
if (V->getType() != NewFnTy->getParamType(i-1))
|
||||
V = new CastInst(V, NewFnTy->getParamType(i-1), V->getName(), CI);
|
||||
|
||||
unsigned *Permutation = getArgumentPermutation(NewFn);
|
||||
unsigned N = NewFnTy->getNumParams();
|
||||
|
||||
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);
|
||||
}
|
||||
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->setCallingConv(CI->getCallingConv());
|
||||
|
||||
if (!CI->use_empty()) {
|
||||
if (NewIsVoid) {
|
||||
CI->replaceAllUsesWith(UndefValue::get(CI->getType()));
|
||||
} else {
|
||||
Instruction *RetVal = NewCI;
|
||||
|
||||
if (F->getReturnType() != NewFn->getReturnType()) {
|
||||
RetVal = new CastInst(NewCI, NewFn->getReturnType(),
|
||||
NewCI->getName(), CI);
|
||||
NewCI->moveBefore(RetVal);
|
||||
}
|
||||
|
||||
CI->replaceAllUsesWith(RetVal);
|
||||
}
|
||||
}
|
||||
CI->eraseFromParent();
|
||||
}
|
||||
|
||||
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();
|
||||
UI != UE; ) {
|
||||
if (CallInst* CI = dyn_cast<CallInst>(*UI++)) {
|
||||
std::vector<Value*> Oprnds;
|
||||
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 (CallInst* CI = dyn_cast<CallInst>(*UI++))
|
||||
UpgradeIntrinsicCall(CI, NewFn);
|
||||
}
|
||||
}
|
||||
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)
|
||||
if (NewFn != F)
|
||||
F->eraseFromParent();
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user