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 -------------------------===//
|
//===------------------------ 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
|
||||||
|
|
||||||
|
@ -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())
|
||||||
|
@ -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:
|
||||||
|
@ -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");
|
||||||
|
@ -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 ||
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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())
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user