forked from OSchip/llvm-project
Make invokes of inline asm legal. Teach codegen
how to lower them (with no attempt made to be efficient, since they should only occur for unoptimized code). llvm-svn: 45108
This commit is contained in:
parent
77b713b5d3
commit
b5a79d0eaa
|
@ -597,7 +597,7 @@ public:
|
||||||
void visitStore(StoreInst &I);
|
void visitStore(StoreInst &I);
|
||||||
void visitPHI(PHINode &I) { } // PHI nodes are handled specially.
|
void visitPHI(PHINode &I) { } // PHI nodes are handled specially.
|
||||||
void visitCall(CallInst &I);
|
void visitCall(CallInst &I);
|
||||||
void visitInlineAsm(CallInst &I);
|
void visitInlineAsm(CallSite CS);
|
||||||
const char *visitIntrinsicCall(CallInst &I, unsigned Intrinsic);
|
const char *visitIntrinsicCall(CallInst &I, unsigned Intrinsic);
|
||||||
void visitTargetIntrinsic(CallInst &I, unsigned Intrinsic);
|
void visitTargetIntrinsic(CallInst &I, unsigned Intrinsic);
|
||||||
|
|
||||||
|
@ -1449,11 +1449,14 @@ void SelectionDAGLowering::visitInvoke(InvokeInst &I) {
|
||||||
MachineBasicBlock *Return = FuncInfo.MBBMap[I.getSuccessor(0)];
|
MachineBasicBlock *Return = FuncInfo.MBBMap[I.getSuccessor(0)];
|
||||||
MachineBasicBlock *LandingPad = FuncInfo.MBBMap[I.getSuccessor(1)];
|
MachineBasicBlock *LandingPad = FuncInfo.MBBMap[I.getSuccessor(1)];
|
||||||
|
|
||||||
LowerCallTo(I, I.getCalledValue()->getType(), I.getParamAttrs(),
|
if (isa<InlineAsm>(I.getCalledValue()))
|
||||||
I.getCallingConv(),
|
visitInlineAsm(&I);
|
||||||
false,
|
else
|
||||||
getValue(I.getOperand(0)),
|
LowerCallTo(I, I.getCalledValue()->getType(), I.getParamAttrs(),
|
||||||
3, LandingPad);
|
I.getCallingConv(),
|
||||||
|
false,
|
||||||
|
getValue(I.getOperand(0)),
|
||||||
|
3, LandingPad);
|
||||||
|
|
||||||
// If the value of the invoke is used outside of its defining block, make it
|
// If the value of the invoke is used outside of its defining block, make it
|
||||||
// available as a virtual register.
|
// available as a virtual register.
|
||||||
|
@ -3044,7 +3047,7 @@ void SelectionDAGLowering::visitCall(CallInst &I) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (isa<InlineAsm>(I.getOperand(0))) {
|
} else if (isa<InlineAsm>(I.getOperand(0))) {
|
||||||
visitInlineAsm(I);
|
visitInlineAsm(&I);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3425,8 +3428,8 @@ GetRegistersForValue(AsmOperandInfo &OpInfo, bool HasEarlyClobber,
|
||||||
|
|
||||||
/// visitInlineAsm - Handle a call to an InlineAsm object.
|
/// visitInlineAsm - Handle a call to an InlineAsm object.
|
||||||
///
|
///
|
||||||
void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
|
void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
|
||||||
InlineAsm *IA = cast<InlineAsm>(I.getOperand(0));
|
InlineAsm *IA = cast<InlineAsm>(CS.getCalledValue());
|
||||||
|
|
||||||
/// ConstraintOperands - Information about all of the constraints.
|
/// ConstraintOperands - Information about all of the constraints.
|
||||||
std::vector<AsmOperandInfo> ConstraintOperands;
|
std::vector<AsmOperandInfo> ConstraintOperands;
|
||||||
|
@ -3446,7 +3449,7 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
|
||||||
// registers, because it will not know to avoid the earlyclobbered output reg.
|
// registers, because it will not know to avoid the earlyclobbered output reg.
|
||||||
bool SawEarlyClobber = false;
|
bool SawEarlyClobber = false;
|
||||||
|
|
||||||
unsigned OpNo = 1; // OpNo - The operand of the CallInst.
|
unsigned ArgNo = 0; // ArgNo - The argument of the CallInst.
|
||||||
for (unsigned i = 0, e = ConstraintInfos.size(); i != e; ++i) {
|
for (unsigned i = 0, e = ConstraintInfos.size(); i != e; ++i) {
|
||||||
ConstraintOperands.push_back(AsmOperandInfo(ConstraintInfos[i]));
|
ConstraintOperands.push_back(AsmOperandInfo(ConstraintInfos[i]));
|
||||||
AsmOperandInfo &OpInfo = ConstraintOperands.back();
|
AsmOperandInfo &OpInfo = ConstraintOperands.back();
|
||||||
|
@ -3459,14 +3462,14 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
|
||||||
if (!OpInfo.isIndirect) {
|
if (!OpInfo.isIndirect) {
|
||||||
// The return value of the call is this value. As such, there is no
|
// The return value of the call is this value. As such, there is no
|
||||||
// corresponding argument.
|
// corresponding argument.
|
||||||
assert(I.getType() != Type::VoidTy && "Bad inline asm!");
|
assert(CS.getType() != Type::VoidTy && "Bad inline asm!");
|
||||||
OpVT = TLI.getValueType(I.getType());
|
OpVT = TLI.getValueType(CS.getType());
|
||||||
} else {
|
} else {
|
||||||
OpInfo.CallOperandVal = I.getOperand(OpNo++);
|
OpInfo.CallOperandVal = CS.getArgument(ArgNo++);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case InlineAsm::isInput:
|
case InlineAsm::isInput:
|
||||||
OpInfo.CallOperandVal = I.getOperand(OpNo++);
|
OpInfo.CallOperandVal = CS.getArgument(ArgNo++);
|
||||||
break;
|
break;
|
||||||
case InlineAsm::isClobber:
|
case InlineAsm::isClobber:
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
|
@ -3617,7 +3620,7 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
|
||||||
// This is the result value of the call.
|
// This is the result value of the call.
|
||||||
assert(RetValRegs.Regs.empty() &&
|
assert(RetValRegs.Regs.empty() &&
|
||||||
"Cannot have multiple output constraints yet!");
|
"Cannot have multiple output constraints yet!");
|
||||||
assert(I.getType() != Type::VoidTy && "Bad inline asm!");
|
assert(CS.getType() != Type::VoidTy && "Bad inline asm!");
|
||||||
RetValRegs = OpInfo.AssignedRegs;
|
RetValRegs = OpInfo.AssignedRegs;
|
||||||
} else {
|
} else {
|
||||||
IndirectStoresToEmit.push_back(std::make_pair(OpInfo.AssignedRegs,
|
IndirectStoresToEmit.push_back(std::make_pair(OpInfo.AssignedRegs,
|
||||||
|
@ -3751,13 +3754,13 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
|
||||||
// width/num elts. Make sure to convert it to the right type with
|
// width/num elts. Make sure to convert it to the right type with
|
||||||
// bit_convert.
|
// bit_convert.
|
||||||
if (MVT::isVector(Val.getValueType())) {
|
if (MVT::isVector(Val.getValueType())) {
|
||||||
const VectorType *VTy = cast<VectorType>(I.getType());
|
const VectorType *VTy = cast<VectorType>(CS.getType());
|
||||||
MVT::ValueType DesiredVT = TLI.getValueType(VTy);
|
MVT::ValueType DesiredVT = TLI.getValueType(VTy);
|
||||||
|
|
||||||
Val = DAG.getNode(ISD::BIT_CONVERT, DesiredVT, Val);
|
Val = DAG.getNode(ISD::BIT_CONVERT, DesiredVT, Val);
|
||||||
}
|
}
|
||||||
|
|
||||||
setValue(&I, Val);
|
setValue(CS.getInstruction(), Val);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<SDOperand, Value*> > StoresToEmit;
|
std::vector<std::pair<SDOperand, Value*> > StoresToEmit;
|
||||||
|
|
|
@ -69,9 +69,8 @@ static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock,
|
||||||
if (!isa<CallInst>(I)) continue;
|
if (!isa<CallInst>(I)) continue;
|
||||||
CallInst *CI = cast<CallInst>(I);
|
CallInst *CI = cast<CallInst>(I);
|
||||||
|
|
||||||
// If this call cannot unwind or is an inline asm, don't
|
// If this call cannot unwind, don't convert it to an invoke.
|
||||||
// convert it to an invoke.
|
if (CI->isNoUnwind())
|
||||||
if (CI->isNoUnwind() || isa<InlineAsm>(CI->getCalledValue()))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Convert this function call into an invoke instruction.
|
// Convert this function call into an invoke instruction.
|
||||||
|
|
|
@ -1123,7 +1123,7 @@ void Verifier::visitInstruction(Instruction &I) {
|
||||||
"Instruction does not dominate all uses!", Op, &I);
|
"Instruction does not dominate all uses!", Op, &I);
|
||||||
}
|
}
|
||||||
} else if (isa<InlineAsm>(I.getOperand(i))) {
|
} else if (isa<InlineAsm>(I.getOperand(i))) {
|
||||||
Assert1(i == 0 && isa<CallInst>(I),
|
Assert1(i == 0 && (isa<CallInst>(I) || isa<InvokeInst>(I)),
|
||||||
"Cannot take the address of an inline asm!", &I);
|
"Cannot take the address of an inline asm!", &I);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
; RUN: llvm-as < %s | llc -enable-eh
|
||||||
|
|
||||||
|
target triple = "i686-pc-linux-gnu"
|
||||||
|
|
||||||
|
define fastcc void @bc__support__high_resolution_time__initialize_clock_rate() {
|
||||||
|
entry:
|
||||||
|
invoke void asm "rdtsc\0A\09movl %eax, $0\0A\09movl %edx, $1", "=*imr,=*imr,~{dirflag},~{fpsr},~{flags},~{dx},~{ax}"( i32* null, i32* null )
|
||||||
|
to label %.noexc unwind label %cleanup144
|
||||||
|
|
||||||
|
.noexc: ; preds = %entry
|
||||||
|
ret void
|
||||||
|
|
||||||
|
cleanup144: ; preds = %entry
|
||||||
|
unwind
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
; RUN: llvm-as < %s | opt -inline -disable-output
|
; RUN: llvm-as < %s | opt -inline | llvm-dis | not grep {invoke void asm}
|
||||||
; PR1335
|
; PR1335
|
||||||
|
|
||||||
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64"
|
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64"
|
||||||
|
|
Loading…
Reference in New Issue