mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-23 12:40:17 +00:00
Recommit r235458: [opaque pointer type] Avoid using PointerType::getElementType for a few cases of CallInst
(reverted in r235533) Original commit message: "Calls to llvm::Value::mutateType are becoming extra-sensitive now that instructions have extra type information that will not be derived from operands or result type (alloca, gep, load, call/invoke, etc... ). The special-handling for mutateType will get more complicated as this work continues - it might be worth making mutateType virtual & pushing the complexity down into the classes that need special handling. But with only two significant uses of mutateType (vectorization and linking) this seems OK for now. Totally open to ideas/suggestions/improvements, of course. With this, and a bunch of exceptions, we can roundtrip an indirect call site through bitcode and IR. (a direct call site is actually trickier... I haven't figured out how to deal with the IR deserializer's lazy construction of Function/GlobalVariable decl's based on the type of the entity which means looking through the "pointer to T" type referring to the global)" The remapping done in ValueMapper for LTO was insufficient as the types weren't correctly mapped (though I was using the post-mapped operands, some of those operands might not have been mapped yet so the type wouldn't be post-mapped yet). Instead use the pre-mapped type and explicitly map all the types. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235651 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d1807ff318
commit
93a23a3bd4
@ -194,6 +194,14 @@ public:
|
||||
CALLSITE_DELEGATE_SETTER(setCallingConv(CC));
|
||||
}
|
||||
|
||||
FunctionType *getFunctionType() const {
|
||||
CALLSITE_DELEGATE_GETTER(getFunctionType());
|
||||
}
|
||||
|
||||
void mutateFunctionType(FunctionType *Ty) const {
|
||||
CALLSITE_DELEGATE_SETTER(mutateFunctionType(Ty));
|
||||
}
|
||||
|
||||
/// getAttributes/setAttributes - get or set the parameter attributes of
|
||||
/// the call.
|
||||
const AttributeSet &getAttributes() const {
|
||||
|
@ -1284,14 +1284,26 @@ public:
|
||||
///
|
||||
class CallInst : public Instruction {
|
||||
AttributeSet AttributeList; ///< parameter attributes for call
|
||||
FunctionType *FTy;
|
||||
CallInst(const CallInst &CI);
|
||||
void init(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr);
|
||||
void init(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr) {
|
||||
init(cast<FunctionType>(
|
||||
cast<PointerType>(Func->getType())->getElementType()),
|
||||
Func, Args, NameStr);
|
||||
}
|
||||
void init(FunctionType *FTy, Value *Func, ArrayRef<Value *> Args,
|
||||
const Twine &NameStr);
|
||||
void init(Value *Func, const Twine &NameStr);
|
||||
|
||||
/// Construct a CallInst given a range of arguments.
|
||||
/// \brief Construct a CallInst from a range of arguments
|
||||
inline CallInst(Value *Func, ArrayRef<Value *> Args,
|
||||
inline CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
|
||||
const Twine &NameStr, Instruction *InsertBefore);
|
||||
inline CallInst(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr,
|
||||
Instruction *InsertBefore)
|
||||
: CallInst(cast<FunctionType>(
|
||||
cast<PointerType>(Func->getType())->getElementType()),
|
||||
Func, Args, NameStr, InsertBefore) {}
|
||||
|
||||
/// Construct a CallInst given a range of arguments.
|
||||
/// \brief Construct a CallInst from a range of arguments
|
||||
@ -1308,8 +1320,15 @@ public:
|
||||
ArrayRef<Value *> Args,
|
||||
const Twine &NameStr = "",
|
||||
Instruction *InsertBefore = nullptr) {
|
||||
return new(unsigned(Args.size() + 1))
|
||||
CallInst(Func, Args, NameStr, InsertBefore);
|
||||
return Create(cast<FunctionType>(
|
||||
cast<PointerType>(Func->getType())->getElementType()),
|
||||
Func, Args, NameStr, InsertBefore);
|
||||
}
|
||||
static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
|
||||
const Twine &NameStr = "",
|
||||
Instruction *InsertBefore = nullptr) {
|
||||
return new (unsigned(Args.size() + 1))
|
||||
CallInst(Ty, Func, Args, NameStr, InsertBefore);
|
||||
}
|
||||
static CallInst *Create(Value *Func,
|
||||
ArrayRef<Value *> Args,
|
||||
@ -1347,9 +1366,11 @@ public:
|
||||
|
||||
~CallInst() override;
|
||||
|
||||
FunctionType *getFunctionType() const {
|
||||
return cast<FunctionType>(
|
||||
cast<PointerType>(getCalledValue()->getType())->getElementType());
|
||||
FunctionType *getFunctionType() const { return FTy; }
|
||||
|
||||
void mutateFunctionType(FunctionType *FTy) {
|
||||
mutateType(FTy->getReturnType());
|
||||
this->FTy = FTy;
|
||||
}
|
||||
|
||||
// Note that 'musttail' implies 'tail'.
|
||||
@ -1533,6 +1554,14 @@ public:
|
||||
|
||||
/// setCalledFunction - Set the function called.
|
||||
void setCalledFunction(Value* Fn) {
|
||||
setCalledFunction(
|
||||
cast<FunctionType>(cast<PointerType>(Fn->getType())->getElementType()),
|
||||
Fn);
|
||||
}
|
||||
void setCalledFunction(FunctionType *FTy, Value *Fn) {
|
||||
this->FTy = FTy;
|
||||
assert(FTy == cast<FunctionType>(
|
||||
cast<PointerType>(Fn->getType())->getElementType()));
|
||||
Op<-1>() = Fn;
|
||||
}
|
||||
|
||||
@ -1573,14 +1602,12 @@ CallInst::CallInst(Value *Func, ArrayRef<Value *> Args,
|
||||
init(Func, Args, NameStr);
|
||||
}
|
||||
|
||||
CallInst::CallInst(Value *Func, ArrayRef<Value *> Args,
|
||||
CallInst::CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
|
||||
const Twine &NameStr, Instruction *InsertBefore)
|
||||
: Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
|
||||
->getElementType())->getReturnType(),
|
||||
Instruction::Call,
|
||||
OperandTraits<CallInst>::op_end(this) - (Args.size() + 1),
|
||||
unsigned(Args.size() + 1), InsertBefore) {
|
||||
init(Func, Args, NameStr);
|
||||
: Instruction(Ty->getReturnType(), Instruction::Call,
|
||||
OperandTraits<CallInst>::op_end(this) - (Args.size() + 1),
|
||||
unsigned(Args.size() + 1), InsertBefore) {
|
||||
init(Ty, Func, Args, NameStr);
|
||||
}
|
||||
|
||||
|
||||
@ -3034,6 +3061,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndirectBrInst, Value)
|
||||
///
|
||||
class InvokeInst : public TerminatorInst {
|
||||
AttributeSet AttributeList;
|
||||
FunctionType *FTy;
|
||||
InvokeInst(const InvokeInst &BI);
|
||||
void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
|
||||
ArrayRef<Value *> Args, const Twine &NameStr);
|
||||
@ -3074,6 +3102,13 @@ public:
|
||||
/// Provide fast operand accessors
|
||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
|
||||
|
||||
FunctionType *getFunctionType() const { return FTy; }
|
||||
|
||||
void mutateFunctionType(FunctionType *FTy) {
|
||||
mutateType(FTy->getReturnType());
|
||||
this->FTy = FTy;
|
||||
}
|
||||
|
||||
/// getNumArgOperands - Return the number of invoke arguments.
|
||||
///
|
||||
unsigned getNumArgOperands() const { return getNumOperands() - 3; }
|
||||
@ -3223,6 +3258,14 @@ public:
|
||||
|
||||
/// setCalledFunction - Set the function called.
|
||||
void setCalledFunction(Value* Fn) {
|
||||
setCalledFunction(
|
||||
cast<FunctionType>(cast<PointerType>(Fn->getType())->getElementType()),
|
||||
Fn);
|
||||
}
|
||||
void setCalledFunction(FunctionType *FTy, Value *Fn) {
|
||||
this->FTy = FTy;
|
||||
assert(FTy == cast<FunctionType>(
|
||||
cast<PointerType>(Fn->getType())->getElementType()));
|
||||
Op<-3>() = Fn;
|
||||
}
|
||||
|
||||
|
@ -5223,7 +5223,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
|
||||
// Finish off the Attribute and check them
|
||||
AttributeSet PAL = AttributeSet::get(Context, Attrs);
|
||||
|
||||
CallInst *CI = CallInst::Create(Callee, Args);
|
||||
CallInst *CI = CallInst::Create(Ty, Callee, Args);
|
||||
CI->setTailCallKind(TCK);
|
||||
CI->setCallingConv(CC);
|
||||
CI->setAttributes(PAL);
|
||||
|
@ -4207,12 +4207,11 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
PointerType *OpTy = dyn_cast<PointerType>(Callee->getType());
|
||||
if (!OpTy)
|
||||
return Error("Callee is not a pointer type");
|
||||
FunctionType *PFTy = dyn_cast<FunctionType>(OpTy->getElementType());
|
||||
if (!PFTy)
|
||||
return Error("Callee is not of pointer to function type");
|
||||
if (!FTy)
|
||||
FTy = PFTy;
|
||||
if (PFTy != FTy)
|
||||
if (!FTy) {
|
||||
FTy = dyn_cast<FunctionType>(OpTy->getElementType());
|
||||
if (!FTy)
|
||||
return Error("Callee is not of pointer to function type");
|
||||
} else if (OpTy->getElementType() != FTy)
|
||||
return Error("Explicit call type does not match pointee type of "
|
||||
"callee operand");
|
||||
if (Record.size() < FTy->getNumParams() + OpNum)
|
||||
@ -4243,7 +4242,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
}
|
||||
}
|
||||
|
||||
I = CallInst::Create(Callee, Args);
|
||||
I = CallInst::Create(FTy, Callee, Args);
|
||||
InstructionList.push_back(I);
|
||||
cast<CallInst>(I)->setCallingConv(
|
||||
static_cast<CallingConv::ID>((~(1U << 14) & CCInfo) >> 1));
|
||||
|
@ -263,14 +263,13 @@ void LandingPadInst::addClause(Constant *Val) {
|
||||
CallInst::~CallInst() {
|
||||
}
|
||||
|
||||
void CallInst::init(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr) {
|
||||
void CallInst::init(FunctionType *FTy, Value *Func, ArrayRef<Value *> Args,
|
||||
const Twine &NameStr) {
|
||||
this->FTy = FTy;
|
||||
assert(NumOperands == Args.size() + 1 && "NumOperands not set up?");
|
||||
Op<-1>() = Func;
|
||||
|
||||
#ifndef NDEBUG
|
||||
FunctionType *FTy =
|
||||
cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
|
||||
|
||||
assert((Args.size() == FTy->getNumParams() ||
|
||||
(FTy->isVarArg() && Args.size() > FTy->getNumParams())) &&
|
||||
"Calling a function with bad signature!");
|
||||
@ -286,15 +285,12 @@ void CallInst::init(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr) {
|
||||
}
|
||||
|
||||
void CallInst::init(Value *Func, const Twine &NameStr) {
|
||||
FTy =
|
||||
cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
|
||||
assert(NumOperands == 1 && "NumOperands not set up?");
|
||||
Op<-1>() = Func;
|
||||
|
||||
#ifndef NDEBUG
|
||||
FunctionType *FTy =
|
||||
cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
|
||||
|
||||
assert(FTy->getNumParams() == 0 && "Calling a function with bad signature");
|
||||
#endif
|
||||
|
||||
setName(NameStr);
|
||||
}
|
||||
@ -320,10 +316,10 @@ CallInst::CallInst(Value *Func, const Twine &Name,
|
||||
}
|
||||
|
||||
CallInst::CallInst(const CallInst &CI)
|
||||
: Instruction(CI.getType(), Instruction::Call,
|
||||
OperandTraits<CallInst>::op_end(this) - CI.getNumOperands(),
|
||||
CI.getNumOperands()) {
|
||||
setAttributes(CI.getAttributes());
|
||||
: Instruction(CI.getType(), Instruction::Call,
|
||||
OperandTraits<CallInst>::op_end(this) - CI.getNumOperands(),
|
||||
CI.getNumOperands()),
|
||||
AttributeList(CI.AttributeList), FTy(CI.FTy) {
|
||||
setTailCallKind(CI.getTailCallKind());
|
||||
setCallingConv(CI.getCallingConv());
|
||||
|
||||
@ -543,15 +539,14 @@ Instruction* CallInst::CreateFree(Value* Source, BasicBlock *InsertAtEnd) {
|
||||
|
||||
void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
|
||||
ArrayRef<Value *> Args, const Twine &NameStr) {
|
||||
FTy = cast<FunctionType>(cast<PointerType>(Fn->getType())->getElementType());
|
||||
|
||||
assert(NumOperands == 3 + Args.size() && "NumOperands not set up?");
|
||||
Op<-3>() = Fn;
|
||||
Op<-2>() = IfNormal;
|
||||
Op<-1>() = IfException;
|
||||
|
||||
#ifndef NDEBUG
|
||||
FunctionType *FTy =
|
||||
cast<FunctionType>(cast<PointerType>(Fn->getType())->getElementType());
|
||||
|
||||
assert(((Args.size() == FTy->getNumParams()) ||
|
||||
(FTy->isVarArg() && Args.size() > FTy->getNumParams())) &&
|
||||
"Invoking a function with bad signature");
|
||||
@ -567,11 +562,11 @@ void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
|
||||
}
|
||||
|
||||
InvokeInst::InvokeInst(const InvokeInst &II)
|
||||
: TerminatorInst(II.getType(), Instruction::Invoke,
|
||||
OperandTraits<InvokeInst>::op_end(this)
|
||||
- II.getNumOperands(),
|
||||
II.getNumOperands()) {
|
||||
setAttributes(II.getAttributes());
|
||||
: TerminatorInst(II.getType(), Instruction::Invoke,
|
||||
OperandTraits<InvokeInst>::op_end(this) -
|
||||
II.getNumOperands(),
|
||||
II.getNumOperands()),
|
||||
AttributeList(II.AttributeList), FTy(II.FTy) {
|
||||
setCallingConv(II.getCallingConv());
|
||||
std::copy(II.op_begin(), II.op_end(), op_begin());
|
||||
SubclassOptionalData = II.SubclassOptionalData;
|
||||
|
@ -2120,7 +2120,11 @@ void Verifier::VerifyCallSite(CallSite CS) {
|
||||
|
||||
Assert(FPTy->getElementType()->isFunctionTy(),
|
||||
"Called function is not pointer to function type!", I);
|
||||
FunctionType *FTy = cast<FunctionType>(FPTy->getElementType());
|
||||
|
||||
Assert(FPTy->getElementType() == CS.getFunctionType(),
|
||||
"Called function is not the same type as the call!", I);
|
||||
|
||||
FunctionType *FTy = CS.getFunctionType();
|
||||
|
||||
// Verify that the correct number of arguments are being passed
|
||||
if (FTy->isVarArg())
|
||||
|
@ -13,6 +13,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Transforms/Utils/ValueMapper.h"
|
||||
#include "llvm/IR/CallSite.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/InlineAsm.h"
|
||||
@ -383,7 +384,18 @@ void llvm::RemapInstruction(Instruction *I, ValueToValueMapTy &VMap,
|
||||
I->setMetadata(MI->first, New);
|
||||
}
|
||||
|
||||
if (!TypeMapper)
|
||||
return;
|
||||
|
||||
// If the instruction's type is being remapped, do so now.
|
||||
if (TypeMapper)
|
||||
if (auto CS = CallSite(I)) {
|
||||
SmallVector<Type *, 3> Tys;
|
||||
FunctionType *FTy = CS.getFunctionType();
|
||||
Tys.reserve(FTy->getNumParams());
|
||||
for (Type *Ty : FTy->params())
|
||||
Tys.push_back(TypeMapper->remapType(Ty));
|
||||
CS.mutateFunctionType(FunctionType::get(
|
||||
TypeMapper->remapType(I->getType()), Tys, FTy->isVarArg()));
|
||||
} else
|
||||
I->mutateType(TypeMapper->remapType(I->getType()));
|
||||
}
|
||||
|
@ -3103,7 +3103,17 @@ namespace {
|
||||
else if (H->hasName())
|
||||
K->takeName(H);
|
||||
|
||||
if (!isa<StoreInst>(K))
|
||||
if (auto CS = CallSite(K)) {
|
||||
SmallVector<Type *, 3> Tys;
|
||||
FunctionType *Old = CS.getFunctionType();
|
||||
unsigned NumOld = Old->getNumParams();
|
||||
assert(NumOld <= ReplacedOperands.size());
|
||||
for (unsigned i = 0; i != NumOld; ++i)
|
||||
Tys.push_back(ReplacedOperands[i]->getType());
|
||||
CS.mutateFunctionType(
|
||||
FunctionType::get(getVecTypeForPair(L->getType(), H->getType()),
|
||||
Tys, Old->isVarArg()));
|
||||
} else if (!isa<StoreInst>(K))
|
||||
K->mutateType(getVecTypeForPair(L->getType(), H->getType()));
|
||||
|
||||
unsigned KnownIDs[] = {
|
||||
|
Loading…
Reference in New Issue
Block a user