summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2016-11-09 22:39:54 +0000
committerTim Northover <tnorthover@apple.com>2016-11-09 22:39:54 +0000
commita9105be437546b3f5398781006c1479c9cfecba8 (patch)
treed0ae6d020f1ddc31e952a761bf20d3824556a613 /llvm/lib/CodeGen
parent58026af7f074dcf198d15d5b80452e178d962ab2 (diff)
downloadbcm5719-llvm-a9105be437546b3f5398781006c1479c9cfecba8.tar.gz
bcm5719-llvm-a9105be437546b3f5398781006c1479c9cfecba8.zip
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. llvm-svn: 286407
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp117
1 files changed, 116 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 79cce6a6f96..24707c53565 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -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::translateKnownIntrinsic(const CallInst &CI,
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 User &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 Constant &C, unsigned Reg) {
return true;
}
-
void IRTranslator::finalizeFunction() {
finishPendingPhis();
@@ -665,6 +779,7 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &MF) {
// 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) {
OpenPOWER on IntegriCloud