llvm.org GIT mirror llvm / fd7b326
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). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45108 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan Sands 12 years ago
5 changed file(s) with 39 addition(s) and 22 deletion(s). Raw diff Collapse all Expand all
596596 void visitStore(StoreInst &I);
597597 void visitPHI(PHINode &I) { } // PHI nodes are handled specially.
598598 void visitCall(CallInst &I);
599 void visitInlineAsm(CallInst &I);
599 void visitInlineAsm(CallSite CS);
600600 const char *visitIntrinsicCall(CallInst &I, unsigned Intrinsic);
601601 void visitTargetIntrinsic(CallInst &I, unsigned Intrinsic);
602602
14481448 MachineBasicBlock *Return = FuncInfo.MBBMap[I.getSuccessor(0)];
14491449 MachineBasicBlock *LandingPad = FuncInfo.MBBMap[I.getSuccessor(1)];
14501450
1451 LowerCallTo(I, I.getCalledValue()->getType(), I.getParamAttrs(),
1452 I.getCallingConv(),
1453 false,
1454 getValue(I.getOperand(0)),
1455 3, LandingPad);
1451 if (isa(I.getCalledValue()))
1452 visitInlineAsm(&I);
1453 else
1454 LowerCallTo(I, I.getCalledValue()->getType(), I.getParamAttrs(),
1455 I.getCallingConv(),
1456 false,
1457 getValue(I.getOperand(0)),
1458 3, LandingPad);
14561459
14571460 // If the value of the invoke is used outside of its defining block, make it
14581461 // available as a virtual register.
30433046 }
30443047 }
30453048 } else if (isa(I.getOperand(0))) {
3046 visitInlineAsm(I);
3049 visitInlineAsm(&I);
30473050 return;
30483051 }
30493052
34243427
34253428 /// visitInlineAsm - Handle a call to an InlineAsm object.
34263429 ///
3427 void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
3428 InlineAsm *IA = cast(I.getOperand(0));
3430 void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
3431 InlineAsm *IA = cast(CS.getCalledValue());
34293432
34303433 /// ConstraintOperands - Information about all of the constraints.
34313434 std::vector ConstraintOperands;
34453448 // registers, because it will not know to avoid the earlyclobbered output reg.
34463449 bool SawEarlyClobber = false;
34473450
3448 unsigned OpNo = 1; // OpNo - The operand of the CallInst.
3451 unsigned ArgNo = 0; // ArgNo - The argument of the CallInst.
34493452 for (unsigned i = 0, e = ConstraintInfos.size(); i != e; ++i) {
34503453 ConstraintOperands.push_back(AsmOperandInfo(ConstraintInfos[i]));
34513454 AsmOperandInfo &OpInfo = ConstraintOperands.back();
34583461 if (!OpInfo.isIndirect) {
34593462 // The return value of the call is this value. As such, there is no
34603463 // corresponding argument.
3461 assert(I.getType() != Type::VoidTy && "Bad inline asm!");
3462 OpVT = TLI.getValueType(I.getType());
3464 assert(CS.getType() != Type::VoidTy && "Bad inline asm!");
3465 OpVT = TLI.getValueType(CS.getType());
34633466 } else {
3464 OpInfo.CallOperandVal = I.getOperand(OpNo++);
3467 OpInfo.CallOperandVal = CS.getArgument(ArgNo++);
34653468 }
34663469 break;
34673470 case InlineAsm::isInput:
3468 OpInfo.CallOperandVal = I.getOperand(OpNo++);
3471 OpInfo.CallOperandVal = CS.getArgument(ArgNo++);
34693472 break;
34703473 case InlineAsm::isClobber:
34713474 // Nothing to do.
36163619 // This is the result value of the call.
36173620 assert(RetValRegs.Regs.empty() &&
36183621 "Cannot have multiple output constraints yet!");
3619 assert(I.getType() != Type::VoidTy && "Bad inline asm!");
3622 assert(CS.getType() != Type::VoidTy && "Bad inline asm!");
36203623 RetValRegs = OpInfo.AssignedRegs;
36213624 } else {
36223625 IndirectStoresToEmit.push_back(std::make_pair(OpInfo.AssignedRegs,
37503753 // width/num elts. Make sure to convert it to the right type with
37513754 // bit_convert.
37523755 if (MVT::isVector(Val.getValueType())) {
3753 const VectorType *VTy = cast(I.getType());
3756 const VectorType *VTy = cast(CS.getType());
37543757 MVT::ValueType DesiredVT = TLI.getValueType(VTy);
37553758
37563759 Val = DAG.getNode(ISD::BIT_CONVERT, DesiredVT, Val);
37573760 }
37583761
3759 setValue(&I, Val);
3762 setValue(CS.getInstruction(), Val);
37603763 }
37613764
37623765 std::vector > StoresToEmit;
6868 if (!isa(I)) continue;
6969 CallInst *CI = cast(I);
7070
71 // If this call cannot unwind or is an inline asm, don't
72 // convert it to an invoke.
73 if (CI->isNoUnwind() || isa(CI->getCalledValue()))
71 // If this call cannot unwind, don't convert it to an invoke.
72 if (CI->isNoUnwind())
7473 continue;
7574
7675 // Convert this function call into an invoke instruction.
11221122 "Instruction does not dominate all uses!", Op, &I);
11231123 }
11241124 } else if (isa(I.getOperand(i))) {
1125 Assert1(i == 0 && isa(I),
1125 Assert1(i == 0 && (isa(I) || isa(I)),
11261126 "Cannot take the address of an inline asm!", &I);
11271127 }
11281128 }
0 ; RUN: llvm-as < %s | llc -enable-eh
1
2 target triple = "i686-pc-linux-gnu"
3
4 define fastcc void @bc__support__high_resolution_time__initialize_clock_rate() {
5 entry:
6 invoke void asm "rdtsc\0A\09movl %eax, $0\0A\09movl %edx, $1", "=*imr,=*imr,~{dirflag},~{fpsr},~{flags},~{dx},~{ax}"( i32* null, i32* null )
7 to label %.noexc unwind label %cleanup144
8
9 .noexc: ; preds = %entry
10 ret void
11
12 cleanup144: ; preds = %entry
13 unwind
14 }
None ; RUN: llvm-as < %s | opt -inline -disable-output
0 ; RUN: llvm-as < %s | opt -inline | llvm-dis | not grep {invoke void asm}
11 ; PR1335
22
33 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"