[llvm] r286407 - GlobalISel: translate invoke and landingpad instructions
Tim Northover via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 9 14:39:54 PST 2016
Author: tnorthover
Date: Wed Nov 9 16:39:54 2016
New Revision: 286407
URL: http://llvm.org/viewvc/llvm-project?rev=286407&view=rev
Log:
GlobalISel: translate invoke and landingpad instructions
Pretty bare-bones support for exception handling (no weird MSVC stuff, no SjLj
etc), but it should get things going.
Added:
llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-exceptions.ll
Modified:
llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h
llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp
Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h?rev=286407&r1=286406&r2=286407&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h Wed Nov 9 16:39:54 2016
@@ -132,6 +132,10 @@ private:
/// \pre \p U is a call instruction.
bool translateCall(const User &U);
+ bool translateInvoke(const User &U);
+
+ bool translateLandingPad(const User &U);
+
/// Translate one of LLVM's cast instructions into MachineInstrs, with the
/// given generic Opcode.
bool translateCast(unsigned Opcode, const User &U);
@@ -287,7 +291,6 @@ private:
// translation.
bool translateSwitch(const User &U) { return false; }
bool translateIndirectBr(const User &U) { return false; }
- bool translateInvoke(const User &U) { return false; }
bool translateResume(const User &U) { return false; }
bool translateCleanupRet(const User &U) { return false; }
bool translateCatchRet(const User &U) { return false; }
@@ -304,7 +307,6 @@ private:
bool translateExtractElement(const User &U) { return false; }
bool translateInsertElement(const User &U) { return false; }
bool translateShuffleVector(const User &U) { return false; }
- bool translateLandingPad(const User &U) { return false; }
/// @}
Modified: llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp?rev=286407&r1=286406&r2=286407&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp Wed Nov 9 16:39:54 2016
@@ -14,8 +14,11 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
+#include "llvm/CodeGen/Analysis.h"
+#include "llvm/CodeGen/FunctionLoweringInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/Constant.h"
@@ -443,6 +446,13 @@ bool IRTranslator::translateKnownIntrins
case Intrinsic::smul_with_overflow: Op = TargetOpcode::G_SMULO; break;
case Intrinsic::memcpy:
return translateMemcpy(CI);
+ case Intrinsic::eh_typeid_for: {
+ GlobalValue *GV = ExtractTypeInfo(CI.getArgOperand(0));
+ unsigned Reg = getOrCreateVReg(CI);
+ unsigned TypeID = MIRBuilder.getMF().getMMI().getTypeIDFor(GV);
+ MIRBuilder.buildConstant(Reg, TypeID);
+ return true;
+ }
case Intrinsic::objectsize: {
// If we don't know by now, we're never going to know.
const ConstantInt *Min = cast<ConstantInt>(CI.getArgOperand(1));
@@ -529,6 +539,111 @@ bool IRTranslator::translateCall(const U
return true;
}
+bool IRTranslator::translateInvoke(const User &U) {
+ const InvokeInst &I = cast<InvokeInst>(U);
+ MachineFunction &MF = MIRBuilder.getMF();
+ MachineModuleInfo &MMI = MF.getMMI();
+
+ const BasicBlock *ReturnBB = I.getSuccessor(0);
+ const BasicBlock *EHPadBB = I.getSuccessor(1);
+
+ const Value *Callee(I.getCalledValue());
+ const Function *Fn = dyn_cast<Function>(Callee);
+ if (isa<InlineAsm>(Callee))
+ return false;
+
+ // FIXME: support invoking patchpoint and statepoint intrinsics.
+ if (Fn && Fn->isIntrinsic())
+ return false;
+
+ // FIXME: support whatever these are.
+ if (I.countOperandBundlesOfType(LLVMContext::OB_deopt))
+ return false;
+
+ // FIXME: support Windows exception handling.
+ if (!isa<LandingPadInst>(EHPadBB->front()))
+ return false;
+
+
+ // Emit the actual call, bracketed by EH_LABELs so that the MMI knows about
+ // the region covered by the try.
+ MCSymbol *BeginSymbol = MMI.getContext().createTempSymbol();
+ MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(BeginSymbol);
+
+ unsigned Res = I.getType()->isVoidTy() ? 0 : getOrCreateVReg(I);
+ SmallVector<CallLowering::ArgInfo, 8> Args;
+ for (auto &Arg: I.arg_operands())
+ Args.emplace_back(getOrCreateVReg(*Arg), Arg->getType());
+
+ if (!CLI->lowerCall(MIRBuilder, MachineOperand::CreateGA(Fn, 0),
+ CallLowering::ArgInfo(Res, I.getType()), Args))
+ return false;
+
+ MCSymbol *EndSymbol = MMI.getContext().createTempSymbol();
+ MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(EndSymbol);
+
+ // FIXME: track probabilities.
+ MachineBasicBlock &EHPadMBB = getOrCreateBB(*EHPadBB),
+ &ReturnMBB = getOrCreateBB(*ReturnBB);
+ MMI.addInvoke(&EHPadMBB, BeginSymbol, EndSymbol);
+ MIRBuilder.getMBB().addSuccessor(&ReturnMBB);
+ MIRBuilder.getMBB().addSuccessor(&EHPadMBB);
+
+ return true;
+}
+
+bool IRTranslator::translateLandingPad(const User &U) {
+ const LandingPadInst &LP = cast<LandingPadInst>(U);
+
+ MachineBasicBlock &MBB = MIRBuilder.getMBB();
+ MachineFunction &MF = MIRBuilder.getMF();
+ MachineModuleInfo &MMI = MF.getMMI();
+ AddLandingPadInfo(LP, MMI, &MBB);
+
+ MBB.setIsEHPad();
+
+ // If there aren't registers to copy the values into (e.g., during SjLj
+ // exceptions), then don't bother.
+ auto &TLI = *MF.getSubtarget().getTargetLowering();
+ const Constant *PersonalityFn = MF.getFunction()->getPersonalityFn();
+ if (TLI.getExceptionPointerRegister(PersonalityFn) == 0 &&
+ TLI.getExceptionSelectorRegister(PersonalityFn) == 0)
+ return true;
+
+ // If landingpad's return type is token type, we don't create DAG nodes
+ // for its exception pointer and selector value. The extraction of exception
+ // pointer or selector value from token type landingpads is not currently
+ // supported.
+ if (LP.getType()->isTokenTy())
+ return true;
+
+ // Add a label to mark the beginning of the landing pad. Deletion of the
+ // landing pad can thus be detected via the MachineModuleInfo.
+ MIRBuilder.buildInstr(TargetOpcode::EH_LABEL)
+ .addSym(MMI.addLandingPad(&MBB));
+
+ // Mark exception register as live in.
+ SmallVector<unsigned, 2> Regs;
+ SmallVector<uint64_t, 2> Offsets;
+ LLT p0 = LLT::pointer(0, DL->getPointerSizeInBits());
+ if (unsigned Reg = TLI.getExceptionPointerRegister(PersonalityFn)) {
+ unsigned VReg = MRI->createGenericVirtualRegister(p0);
+ MIRBuilder.buildCopy(VReg, Reg);
+ Regs.push_back(VReg);
+ Offsets.push_back(0);
+ }
+
+ if (unsigned Reg = TLI.getExceptionSelectorRegister(PersonalityFn)) {
+ unsigned VReg = MRI->createGenericVirtualRegister(p0);
+ MIRBuilder.buildCopy(VReg, Reg);
+ Regs.push_back(VReg);
+ Offsets.push_back(p0.getSizeInBits());
+ }
+
+ MIRBuilder.buildSequence(getOrCreateVReg(LP), Regs, Offsets);
+ return true;
+}
+
bool IRTranslator::translateStaticAlloca(const AllocaInst &AI) {
if (!TPC->isGlobalISelAbortEnabled() && !AI.isStaticAlloca())
return false;
@@ -613,7 +728,6 @@ bool IRTranslator::translate(const Const
return true;
}
-
void IRTranslator::finalizeFunction() {
finishPendingPhis();
@@ -665,6 +779,7 @@ bool IRTranslator::runOnMachineFunction(
// Set the insertion point of all the following translations to
// the end of this basic block.
MIRBuilder.setMBB(MBB);
+
for (const Instruction &Inst: BB) {
bool Succeeded = translate(Inst);
if (!Succeeded) {
Modified: llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp?rev=286407&r1=286406&r2=286407&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp Wed Nov 9 16:39:54 2016
@@ -915,7 +915,7 @@ bool AArch64InstructionSelector::select(
.addUse(SrcXReg)
.addImm(0)
.addImm(SrcTy.getSizeInBits() - 1);
- } else if (DstTy == LLT::scalar(32)) {
+ } else if (DstTy.isScalar() && DstTy.getSizeInBits() <= 32) {
const unsigned NewOpc = isSigned ? AArch64::SBFMWri : AArch64::UBFMWri;
ExtI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
.addDef(DefReg)
Added: llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-exceptions.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-exceptions.ll?rev=286407&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-exceptions.ll (added)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-exceptions.ll Wed Nov 9 16:39:54 2016
@@ -0,0 +1,44 @@
+; RUN: llc -O0 -mtriple=aarch64-apple-ios -global-isel -stop-after=irtranslator %s -o - | FileCheck %s
+
+ at _ZTIi = external global i8*
+
+declare i32 @foo(i32)
+declare i32 @__gxx_personality_v0(...)
+declare i32 @llvm.eh.typeid.for(i8*)
+
+; CHECK: name: bar
+; CHECK: body:
+; CHECK: bb.0:
+; CHECK: successors: %bb.2{{.*}}%bb.1
+; CHECK: EH_LABEL
+; CHECK: %w0 = COPY
+; CHECK: BL @foo, csr_aarch64_aapcs, implicit-def %lr, implicit %sp, implicit %w0, implicit-def %w0
+; CHECK: {{%[0-9]+}}(s32) = COPY %w0
+; CHECK: EH_LABEL
+
+; CHECK: bb.1
+; CHECK: EH_LABEL
+; CHECK: [[PTR:%[0-9]+]](p0) = COPY %x0
+; CHECK: [[SEL:%[0-9]+]](p0) = COPY %x1
+; CHECK: [[PTR_SEL:%[0-9]+]](s128) = G_SEQUENCE [[PTR]](p0), 0, [[SEL]](p0), 64
+; CHECK: [[PTR_RET:%[0-9]+]](s64), [[SEL_RET:%[0-9]+]](s32) = G_EXTRACT [[PTR_SEL]](s128), 0, 64
+; CHECK: %x0 = COPY [[PTR_RET]]
+; CHECK: %w1 = COPY [[SEL_RET]]
+
+; CHECK: bb.2:
+; CHECK: [[SEL:%[0-9]+]](s32) = G_CONSTANT 1
+; CHECK: {{%[0-9]+}}(s128) = G_INSERT {{%[0-9]+}}(s128), [[SEL]](s32), 64
+
+define { i8*, i32 } @bar() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+ %res32 = invoke i32 @foo(i32 42) to label %continue unwind label %broken
+
+
+broken:
+ %ptr.sel = landingpad { i8*, i32 } catch i8* bitcast(i8** @_ZTIi to i8*)
+ ret { i8*, i32 } %ptr.sel
+
+continue:
+ %sel.int = tail call i32 @llvm.eh.typeid.for(i8* bitcast(i8** @_ZTIi to i8*))
+ %res.good = insertvalue { i8*, i32 } undef, i32 %sel.int, 1
+ ret { i8*, i32 } %res.good
+}
More information about the llvm-commits
mailing list