2009-11-24 01:16:22 +08:00
|
|
|
//===-- FunctionLoweringInfo.cpp ------------------------------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This implements routines for translating functions from LLVM IR into
|
|
|
|
// Machine IR.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-07-08 00:01:37 +08:00
|
|
|
#include "llvm/CodeGen/FunctionLoweringInfo.h"
|
2012-12-04 00:50:05 +08:00
|
|
|
#include "llvm/ADT/PostOrderIterator.h"
|
|
|
|
#include "llvm/CodeGen/Analysis.h"
|
|
|
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
|
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
|
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
|
|
|
#include "llvm/CodeGen/MachineModuleInfo.h"
|
|
|
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
2015-03-31 06:58:10 +08:00
|
|
|
#include "llvm/CodeGen/WinEHFuncInfo.h"
|
2013-01-02 19:36:10 +08:00
|
|
|
#include "llvm/IR/DataLayout.h"
|
2014-03-06 08:46:21 +08:00
|
|
|
#include "llvm/IR/DebugInfo.h"
|
2013-01-02 19:36:10 +08:00
|
|
|
#include "llvm/IR/DerivedTypes.h"
|
|
|
|
#include "llvm/IR/Function.h"
|
|
|
|
#include "llvm/IR/Instructions.h"
|
|
|
|
#include "llvm/IR/IntrinsicInst.h"
|
|
|
|
#include "llvm/IR/LLVMContext.h"
|
|
|
|
#include "llvm/IR/Module.h"
|
2009-11-24 01:16:22 +08:00
|
|
|
#include "llvm/Support/Debug.h"
|
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
|
|
#include "llvm/Support/MathExtras.h"
|
2015-03-24 03:32:43 +08:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2014-03-05 10:43:26 +08:00
|
|
|
#include "llvm/Target/TargetFrameLowering.h"
|
2014-03-05 18:30:38 +08:00
|
|
|
#include "llvm/Target/TargetInstrInfo.h"
|
2012-12-04 00:50:05 +08:00
|
|
|
#include "llvm/Target/TargetLowering.h"
|
|
|
|
#include "llvm/Target/TargetOptions.h"
|
|
|
|
#include "llvm/Target/TargetRegisterInfo.h"
|
2014-08-05 05:25:23 +08:00
|
|
|
#include "llvm/Target/TargetSubtargetInfo.h"
|
2009-11-24 01:16:22 +08:00
|
|
|
#include <algorithm>
|
|
|
|
using namespace llvm;
|
|
|
|
|
2014-04-22 10:02:50 +08:00
|
|
|
#define DEBUG_TYPE "function-lowering-info"
|
|
|
|
|
2009-11-24 01:16:22 +08:00
|
|
|
/// isUsedOutsideOfDefiningBlock - Return true if this instruction is used by
|
|
|
|
/// PHI nodes or outside of the basic block that defines it, or used by a
|
|
|
|
/// switch or atomic instruction, which may expand to multiple basic blocks.
|
2010-04-15 12:33:49 +08:00
|
|
|
static bool isUsedOutsideOfDefiningBlock(const Instruction *I) {
|
2010-04-20 22:50:13 +08:00
|
|
|
if (I->use_empty()) return false;
|
2009-11-24 01:16:22 +08:00
|
|
|
if (isa<PHINode>(I)) return true;
|
2010-04-15 12:33:49 +08:00
|
|
|
const BasicBlock *BB = I->getParent();
|
2014-03-09 11:16:01 +08:00
|
|
|
for (const User *U : I->users())
|
2010-07-10 00:08:33 +08:00
|
|
|
if (cast<Instruction>(U)->getParent() != BB || isa<PHINode>(U))
|
2009-11-24 01:16:22 +08:00
|
|
|
return true;
|
2014-03-09 11:16:01 +08:00
|
|
|
|
2009-11-24 01:16:22 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-09-19 13:30:35 +08:00
|
|
|
static ISD::NodeType getPreferredExtendForValue(const Value *V) {
|
|
|
|
// For the users of the source value being used for compare instruction, if
|
|
|
|
// the number of signed predicate is greater than unsigned predicate, we
|
|
|
|
// prefer to use SIGN_EXTEND.
|
|
|
|
//
|
|
|
|
// With this optimization, we would be able to reduce some redundant sign or
|
|
|
|
// zero extension instruction, and eventually more machine CSE opportunities
|
|
|
|
// can be exposed.
|
|
|
|
ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
|
|
|
|
unsigned NumOfSigned = 0, NumOfUnsigned = 0;
|
|
|
|
for (const User *U : V->users()) {
|
|
|
|
if (const auto *CI = dyn_cast<CmpInst>(U)) {
|
|
|
|
NumOfSigned += CI->isSigned();
|
|
|
|
NumOfUnsigned += CI->isUnsigned();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (NumOfSigned > NumOfUnsigned)
|
|
|
|
ExtendKind = ISD::SIGN_EXTEND;
|
|
|
|
|
|
|
|
return ExtendKind;
|
|
|
|
}
|
|
|
|
|
2015-03-31 06:58:10 +08:00
|
|
|
namespace {
|
|
|
|
struct WinEHNumbering {
|
2015-05-12 03:41:19 +08:00
|
|
|
WinEHNumbering(WinEHFuncInfo &FuncInfo) : FuncInfo(FuncInfo),
|
|
|
|
CurrentBaseState(-1), NextState(0) {}
|
2015-03-31 06:58:10 +08:00
|
|
|
|
|
|
|
WinEHFuncInfo &FuncInfo;
|
2015-05-12 03:41:19 +08:00
|
|
|
int CurrentBaseState;
|
2015-03-31 06:58:10 +08:00
|
|
|
int NextState;
|
|
|
|
|
|
|
|
SmallVector<ActionHandler *, 4> HandlerStack;
|
2015-04-01 06:35:44 +08:00
|
|
|
SmallPtrSet<const Function *, 4> VisitedHandlers;
|
2015-03-31 06:58:10 +08:00
|
|
|
|
|
|
|
int currentEHNumber() const {
|
2015-05-12 03:41:19 +08:00
|
|
|
return HandlerStack.empty() ? CurrentBaseState : HandlerStack.back()->getEHState();
|
2015-03-31 06:58:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void createUnwindMapEntry(int ToState, ActionHandler *AH);
|
2015-04-01 06:35:44 +08:00
|
|
|
void createTryBlockMapEntry(int TryLow, int TryHigh,
|
|
|
|
ArrayRef<CatchHandler *> Handlers);
|
|
|
|
void processCallSite(ArrayRef<ActionHandler *> Actions, ImmutableCallSite CS);
|
2015-03-31 06:58:10 +08:00
|
|
|
void calculateStateNumbers(const Function &F);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2014-03-05 10:43:26 +08:00
|
|
|
void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
|
|
|
|
SelectionDAG *DAG) {
|
2009-11-24 01:16:22 +08:00
|
|
|
Fn = &fn;
|
|
|
|
MF = &mf;
|
2014-10-09 08:57:31 +08:00
|
|
|
TLI = MF->getSubtarget().getTargetLowering();
|
2009-11-24 01:16:22 +08:00
|
|
|
RegInfo = &MF->getRegInfo();
|
2015-03-31 06:58:10 +08:00
|
|
|
MachineModuleInfo &MMI = MF->getMMI();
|
2009-11-24 01:16:22 +08:00
|
|
|
|
2010-07-10 17:00:22 +08:00
|
|
|
// Check whether the function can return without sret-demotion.
|
|
|
|
SmallVector<ISD::OutputArg, 4> Outs;
|
2013-06-06 08:11:39 +08:00
|
|
|
GetReturnInfo(Fn->getReturnType(), Fn->getAttributes(), Outs, *TLI);
|
|
|
|
CanLowerReturn = TLI->CanLowerReturn(Fn->getCallingConv(), *MF,
|
2014-10-09 08:57:31 +08:00
|
|
|
Fn->isVarArg(), Outs, Fn->getContext());
|
2010-07-10 17:00:22 +08:00
|
|
|
|
2009-11-24 01:16:22 +08:00
|
|
|
// Initialize the mapping of values to registers. This is only set up for
|
|
|
|
// instruction values that are used outside of the block that defines
|
|
|
|
// them.
|
2010-04-15 12:33:49 +08:00
|
|
|
Function::const_iterator BB = Fn->begin(), EB = Fn->end();
|
2009-11-24 01:16:22 +08:00
|
|
|
for (; BB != EB; ++BB)
|
2012-02-24 09:59:01 +08:00
|
|
|
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
|
|
|
|
I != E; ++I) {
|
2014-03-05 10:43:26 +08:00
|
|
|
if (const AllocaInst *AI = dyn_cast<AllocaInst>(I)) {
|
2014-09-03 02:42:44 +08:00
|
|
|
// Static allocas can be folded into the initial stack frame adjustment.
|
|
|
|
if (AI->isStaticAlloca()) {
|
|
|
|
const ConstantInt *CUI = cast<ConstantInt>(AI->getArraySize());
|
|
|
|
Type *Ty = AI->getAllocatedType();
|
|
|
|
uint64_t TySize = TLI->getDataLayout()->getTypeAllocSize(Ty);
|
|
|
|
unsigned Align =
|
2014-10-09 08:57:31 +08:00
|
|
|
std::max((unsigned)TLI->getDataLayout()->getPrefTypeAlignment(Ty),
|
|
|
|
AI->getAlignment());
|
2014-09-03 02:42:44 +08:00
|
|
|
|
|
|
|
TySize *= CUI->getZExtValue(); // Get total allocated size.
|
|
|
|
if (TySize == 0) TySize = 1; // Don't create zero-sized stack objects.
|
|
|
|
|
|
|
|
StaticAllocaMap[AI] =
|
|
|
|
MF->getFrameInfo()->CreateStackObject(TySize, Align, false, AI);
|
|
|
|
|
|
|
|
} else {
|
2014-03-05 10:43:26 +08:00
|
|
|
unsigned Align = std::max(
|
|
|
|
(unsigned)TLI->getDataLayout()->getPrefTypeAlignment(
|
|
|
|
AI->getAllocatedType()),
|
|
|
|
AI->getAlignment());
|
2014-08-05 05:25:23 +08:00
|
|
|
unsigned StackAlign =
|
2014-10-09 08:57:31 +08:00
|
|
|
MF->getSubtarget().getFrameLowering()->getStackAlignment();
|
2014-03-05 10:43:26 +08:00
|
|
|
if (Align <= StackAlign)
|
|
|
|
Align = 0;
|
|
|
|
// Inform the Frame Information that we have variable-sized objects.
|
|
|
|
MF->getFrameInfo()->CreateVariableSizedObject(Align ? Align : 1, AI);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Look for inline asm that clobbers the SP register.
|
|
|
|
if (isa<CallInst>(I) || isa<InvokeInst>(I)) {
|
|
|
|
ImmutableCallSite CS(I);
|
2014-03-05 11:21:23 +08:00
|
|
|
if (isa<InlineAsm>(CS.getCalledValue())) {
|
2014-03-05 10:43:26 +08:00
|
|
|
unsigned SP = TLI->getStackPointerRegisterToSaveRestore();
|
2015-02-27 06:38:43 +08:00
|
|
|
const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
|
2014-03-05 10:43:26 +08:00
|
|
|
std::vector<TargetLowering::AsmOperandInfo> Ops =
|
2015-02-27 06:38:43 +08:00
|
|
|
TLI->ParseConstraints(TRI, CS);
|
2014-03-05 10:43:26 +08:00
|
|
|
for (size_t I = 0, E = Ops.size(); I != E; ++I) {
|
|
|
|
TargetLowering::AsmOperandInfo &Op = Ops[I];
|
|
|
|
if (Op.Type == InlineAsm::isClobber) {
|
|
|
|
// Clobbers don't have SDValue operands, hence SDValue().
|
|
|
|
TLI->ComputeConstraintToUse(Op, SDValue(), DAG);
|
2014-10-09 08:57:31 +08:00
|
|
|
std::pair<unsigned, const TargetRegisterClass *> PhysReg =
|
2015-02-27 06:38:43 +08:00
|
|
|
TLI->getRegForInlineAsmConstraint(TRI, Op.ConstraintCode,
|
|
|
|
Op.ConstraintVT);
|
2014-03-05 10:43:26 +08:00
|
|
|
if (PhysReg.first == SP)
|
|
|
|
MF->getFrameInfo()->setHasInlineAsmWithSPAdjust(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-23 05:59:26 +08:00
|
|
|
// Look for calls to the @llvm.va_start intrinsic. We can omit some
|
|
|
|
// prologue boilerplate for variadic functions that don't examine their
|
|
|
|
// arguments.
|
|
|
|
if (const auto *II = dyn_cast<IntrinsicInst>(I)) {
|
|
|
|
if (II->getIntrinsicID() == Intrinsic::vastart)
|
|
|
|
MF->getFrameInfo()->setHasVAStart(true);
|
|
|
|
}
|
|
|
|
|
2014-08-30 05:42:08 +08:00
|
|
|
// If we have a musttail call in a variadic funciton, we need to ensure we
|
|
|
|
// forward implicit register parameters.
|
2014-08-30 05:42:21 +08:00
|
|
|
if (const auto *CI = dyn_cast<CallInst>(I)) {
|
2014-08-30 05:42:08 +08:00
|
|
|
if (CI->isMustTailCall() && Fn->isVarArg())
|
|
|
|
MF->getFrameInfo()->setHasMustTailInVarArgFunc(true);
|
|
|
|
}
|
|
|
|
|
2010-07-17 01:54:27 +08:00
|
|
|
// Mark values used outside their block as exported, by allocating
|
|
|
|
// a virtual register for them.
|
2011-02-22 11:24:52 +08:00
|
|
|
if (isUsedOutsideOfDefiningBlock(I))
|
2009-11-24 01:16:22 +08:00
|
|
|
if (!isa<AllocaInst>(I) ||
|
|
|
|
!StaticAllocaMap.count(cast<AllocaInst>(I)))
|
|
|
|
InitializeRegForValue(I);
|
|
|
|
|
2010-07-17 01:54:27 +08:00
|
|
|
// Collect llvm.dbg.declare information. This is done now instead of
|
|
|
|
// during the initial isel pass through the IR so that it is done
|
|
|
|
// in a predictable order.
|
|
|
|
if (const DbgDeclareInst *DI = dyn_cast<DbgDeclareInst>(I)) {
|
2015-04-22 02:24:23 +08:00
|
|
|
assert(DI->getVariable() && "Missing variable");
|
|
|
|
assert(DI->getDebugLoc() && "Missing location");
|
|
|
|
if (MMI.hasDebugInfo()) {
|
2010-07-17 01:54:27 +08:00
|
|
|
// Don't handle byval struct arguments or VLAs, for example.
|
|
|
|
// Non-byval arguments are handled here (they refer to the stack
|
|
|
|
// temporary alloca at this point).
|
|
|
|
const Value *Address = DI->getAddress();
|
|
|
|
if (Address) {
|
|
|
|
if (const BitCastInst *BCI = dyn_cast<BitCastInst>(Address))
|
|
|
|
Address = BCI->getOperand(0);
|
|
|
|
if (const AllocaInst *AI = dyn_cast<AllocaInst>(Address)) {
|
|
|
|
DenseMap<const AllocaInst *, int>::iterator SI =
|
|
|
|
StaticAllocaMap.find(AI);
|
|
|
|
if (SI != StaticAllocaMap.end()) { // Check for VLAs.
|
|
|
|
int FI = SI->second;
|
Move the complex address expression out of DIVariable and into an extra
argument of the llvm.dbg.declare/llvm.dbg.value intrinsics.
Previously, DIVariable was a variable-length field that has an optional
reference to a Metadata array consisting of a variable number of
complex address expressions. In the case of OpPiece expressions this is
wasting a lot of storage in IR, because when an aggregate type is, e.g.,
SROA'd into all of its n individual members, the IR will contain n copies
of the DIVariable, all alike, only differing in the complex address
reference at the end.
By making the complex address into an extra argument of the
dbg.value/dbg.declare intrinsics, all of the pieces can reference the
same variable and the complex address expressions can be uniqued across
the CU, too.
Down the road, this will allow us to move other flags, such as
"indirection" out of the DIVariable, too.
The new intrinsics look like this:
declare void @llvm.dbg.declare(metadata %storage, metadata %var, metadata %expr)
declare void @llvm.dbg.value(metadata %storage, i64 %offset, metadata %var, metadata %expr)
This patch adds a new LLVM-local tag to DIExpressions, so we can detect
and pretty-print DIExpression metadata nodes.
What this patch doesn't do:
This patch does not touch the "Indirect" field in DIVariable; but moving
that into the expression would be a natural next step.
http://reviews.llvm.org/D4919
rdar://problem/17994491
Thanks to dblaikie and dexonsmith for reviewing this patch!
Note: I accidentally committed a bogus older version of this patch previously.
llvm-svn: 218787
2014-10-02 02:55:02 +08:00
|
|
|
MMI.setVariableDbgInfo(DI->getVariable(), DI->getExpression(),
|
2010-07-17 01:54:27 +08:00
|
|
|
FI, DI->getDebugLoc());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-09-19 13:30:35 +08:00
|
|
|
|
|
|
|
// Decide the preferred extend type for a value.
|
|
|
|
PreferredExtendType[I] = getPreferredExtendForValue(I);
|
2010-07-17 01:54:27 +08:00
|
|
|
}
|
|
|
|
|
2009-11-24 01:16:22 +08:00
|
|
|
// Create an initial MachineBasicBlock for each LLVM BasicBlock in F. This
|
|
|
|
// also creates the initial PHI MachineInstrs, though none of the input
|
|
|
|
// operands are populated.
|
2010-04-15 00:30:40 +08:00
|
|
|
for (BB = Fn->begin(); BB != EB; ++BB) {
|
2009-11-24 01:16:22 +08:00
|
|
|
MachineBasicBlock *MBB = mf.CreateMachineBasicBlock(BB);
|
|
|
|
MBBMap[BB] = MBB;
|
|
|
|
MF->push_back(MBB);
|
|
|
|
|
|
|
|
// Transfer the address-taken flag. This is necessary because there could
|
|
|
|
// be multiple MachineBasicBlocks corresponding to one BasicBlock, and only
|
|
|
|
// the first one should be marked.
|
|
|
|
if (BB->hasAddressTaken())
|
|
|
|
MBB->setHasAddressTaken();
|
|
|
|
|
|
|
|
// Create Machine PHI nodes for LLVM PHI nodes, lowering them as
|
|
|
|
// appropriate.
|
2010-04-20 22:46:25 +08:00
|
|
|
for (BasicBlock::const_iterator I = BB->begin();
|
|
|
|
const PHINode *PN = dyn_cast<PHINode>(I); ++I) {
|
|
|
|
if (PN->use_empty()) continue;
|
2009-11-24 01:16:22 +08:00
|
|
|
|
2011-05-13 23:18:06 +08:00
|
|
|
// Skip empty types
|
|
|
|
if (PN->getType()->isEmptyTy())
|
|
|
|
continue;
|
|
|
|
|
2010-04-20 22:48:02 +08:00
|
|
|
DebugLoc DL = PN->getDebugLoc();
|
2009-11-24 01:16:22 +08:00
|
|
|
unsigned PHIReg = ValueMap[PN];
|
|
|
|
assert(PHIReg && "PHI node does not have an assigned virtual register!");
|
|
|
|
|
|
|
|
SmallVector<EVT, 4> ValueVTs;
|
2013-06-06 08:11:39 +08:00
|
|
|
ComputeValueVTs(*TLI, PN->getType(), ValueVTs);
|
2009-11-24 01:16:22 +08:00
|
|
|
for (unsigned vti = 0, vte = ValueVTs.size(); vti != vte; ++vti) {
|
|
|
|
EVT VT = ValueVTs[vti];
|
2013-06-06 08:11:39 +08:00
|
|
|
unsigned NumRegisters = TLI->getNumRegisters(Fn->getContext(), VT);
|
2014-08-05 10:39:49 +08:00
|
|
|
const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
|
2009-11-24 01:16:22 +08:00
|
|
|
for (unsigned i = 0; i != NumRegisters; ++i)
|
2010-02-10 03:54:29 +08:00
|
|
|
BuildMI(MBB, DL, TII->get(TargetOpcode::PHI), PHIReg + i);
|
2009-11-24 01:16:22 +08:00
|
|
|
PHIReg += NumRegisters;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-04-15 00:32:56 +08:00
|
|
|
|
|
|
|
// Mark landing pad blocks.
|
2015-04-25 04:25:05 +08:00
|
|
|
SmallVector<const LandingPadInst *, 4> LPads;
|
2015-04-22 02:23:57 +08:00
|
|
|
for (BB = Fn->begin(); BB != EB; ++BB) {
|
2015-03-31 06:58:10 +08:00
|
|
|
if (const auto *Invoke = dyn_cast<InvokeInst>(BB->getTerminator()))
|
2010-04-15 00:32:56 +08:00
|
|
|
MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad();
|
2015-04-22 02:23:57 +08:00
|
|
|
if (BB->isLandingPad())
|
2015-04-25 04:25:05 +08:00
|
|
|
LPads.push_back(BB->getLandingPadInst());
|
2015-04-22 02:23:57 +08:00
|
|
|
}
|
2015-03-31 06:58:10 +08:00
|
|
|
|
2015-04-25 04:25:05 +08:00
|
|
|
// If this is an MSVC EH personality, we need to do a bit more work.
|
2015-04-22 02:23:57 +08:00
|
|
|
EHPersonality Personality = EHPersonality::Unknown;
|
2015-04-25 04:25:05 +08:00
|
|
|
if (!LPads.empty())
|
|
|
|
Personality = classifyEHPersonality(LPads.back()->getPersonalityFn());
|
|
|
|
if (!isMSVCEHPersonality(Personality))
|
|
|
|
return;
|
|
|
|
|
|
|
|
WinEHFuncInfo *EHInfo = nullptr;
|
2015-04-22 02:23:57 +08:00
|
|
|
if (Personality == EHPersonality::MSVC_Win64SEH) {
|
2015-04-25 04:25:05 +08:00
|
|
|
addSEHHandlersForLPads(LPads);
|
2015-04-22 02:23:57 +08:00
|
|
|
} else if (Personality == EHPersonality::MSVC_CXX) {
|
2015-04-10 12:56:17 +08:00
|
|
|
const Function *WinEHParentFn = MMI.getWinEHParent(&fn);
|
2015-04-25 04:25:05 +08:00
|
|
|
EHInfo = &MMI.getWinEHFuncInfo(WinEHParentFn);
|
|
|
|
if (EHInfo->LandingPadStateMap.empty()) {
|
|
|
|
WinEHNumbering Num(*EHInfo);
|
2015-04-10 12:56:17 +08:00
|
|
|
Num.calculateStateNumbers(*WinEHParentFn);
|
|
|
|
// Pop everything on the handler stack.
|
|
|
|
Num.processCallSite(None, ImmutableCallSite());
|
|
|
|
}
|
2015-04-25 04:25:05 +08:00
|
|
|
|
|
|
|
// Copy the state numbers to LandingPadInfo for the current function, which
|
|
|
|
// could be a handler or the parent.
|
|
|
|
for (const LandingPadInst *LP : LPads) {
|
|
|
|
MachineBasicBlock *LPadMBB = MBBMap[LP->getParent()];
|
|
|
|
MMI.addWinEHState(LPadMBB, EHInfo->LandingPadStateMap[LP]);
|
|
|
|
}
|
2015-04-01 06:35:44 +08:00
|
|
|
}
|
2015-03-31 06:58:10 +08:00
|
|
|
}
|
|
|
|
|
2015-04-25 04:25:05 +08:00
|
|
|
void FunctionLoweringInfo::addSEHHandlersForLPads(
|
|
|
|
ArrayRef<const LandingPadInst *> LPads) {
|
2015-04-22 02:23:57 +08:00
|
|
|
MachineModuleInfo &MMI = MF->getMMI();
|
|
|
|
|
|
|
|
// Iterate over all landing pads with llvm.eh.actions calls.
|
2015-04-25 04:25:05 +08:00
|
|
|
for (const LandingPadInst *LP : LPads) {
|
2015-04-22 02:23:57 +08:00
|
|
|
const IntrinsicInst *ActionsCall =
|
|
|
|
dyn_cast<IntrinsicInst>(LP->getNextNode());
|
|
|
|
if (!ActionsCall ||
|
|
|
|
ActionsCall->getIntrinsicID() != Intrinsic::eh_actions)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Parse the llvm.eh.actions call we found.
|
|
|
|
MachineBasicBlock *LPadMBB = MBBMap[LP->getParent()];
|
|
|
|
SmallVector<ActionHandler *, 4> Actions;
|
|
|
|
parseEHActions(ActionsCall, Actions);
|
|
|
|
|
|
|
|
// Iterate EH actions from most to least precedence, which means
|
|
|
|
// iterating in reverse.
|
|
|
|
for (auto I = Actions.rbegin(), E = Actions.rend(); I != E; ++I) {
|
|
|
|
ActionHandler *Action = *I;
|
|
|
|
if (auto *CH = dyn_cast<CatchHandler>(Action)) {
|
|
|
|
const auto *Filter =
|
|
|
|
dyn_cast<Function>(CH->getSelector()->stripPointerCasts());
|
|
|
|
assert((Filter || CH->getSelector()->isNullValue()) &&
|
|
|
|
"expected function or catch-all");
|
|
|
|
const auto *RecoverBA =
|
|
|
|
cast<BlockAddress>(CH->getHandlerBlockOrFunc());
|
|
|
|
MMI.addSEHCatchHandler(LPadMBB, Filter, RecoverBA);
|
|
|
|
} else {
|
|
|
|
assert(isa<CleanupHandler>(Action));
|
|
|
|
const auto *Fini = cast<Function>(Action->getHandlerBlockOrFunc());
|
|
|
|
MMI.addSEHCleanupHandler(LPadMBB, Fini);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DeleteContainerPointers(Actions);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-31 06:58:10 +08:00
|
|
|
void WinEHNumbering::createUnwindMapEntry(int ToState, ActionHandler *AH) {
|
|
|
|
WinEHUnwindMapEntry UME;
|
|
|
|
UME.ToState = ToState;
|
2015-04-01 06:35:44 +08:00
|
|
|
if (auto *CH = dyn_cast_or_null<CleanupHandler>(AH))
|
2015-03-31 06:58:10 +08:00
|
|
|
UME.Cleanup = cast<Function>(CH->getHandlerBlockOrFunc());
|
|
|
|
else
|
|
|
|
UME.Cleanup = nullptr;
|
|
|
|
FuncInfo.UnwindMap.push_back(UME);
|
|
|
|
}
|
|
|
|
|
2015-04-01 06:35:44 +08:00
|
|
|
void WinEHNumbering::createTryBlockMapEntry(int TryLow, int TryHigh,
|
|
|
|
ArrayRef<CatchHandler *> Handlers) {
|
|
|
|
WinEHTryBlockMapEntry TBME;
|
|
|
|
TBME.TryLow = TryLow;
|
|
|
|
TBME.TryHigh = TryHigh;
|
|
|
|
assert(TBME.TryLow <= TBME.TryHigh);
|
|
|
|
for (CatchHandler *CH : Handlers) {
|
|
|
|
WinEHHandlerType HT;
|
2015-04-01 13:20:42 +08:00
|
|
|
if (CH->getSelector()->isNullValue()) {
|
|
|
|
HT.Adjectives = 0x40;
|
|
|
|
HT.TypeDescriptor = nullptr;
|
|
|
|
} else {
|
|
|
|
auto *GV = cast<GlobalVariable>(CH->getSelector()->stripPointerCasts());
|
|
|
|
// Selectors are always pointers to GlobalVariables with 'struct' type.
|
|
|
|
// The struct has two fields, adjectives and a type descriptor.
|
|
|
|
auto *CS = cast<ConstantStruct>(GV->getInitializer());
|
|
|
|
HT.Adjectives =
|
|
|
|
cast<ConstantInt>(CS->getAggregateElement(0U))->getZExtValue();
|
|
|
|
HT.TypeDescriptor =
|
|
|
|
cast<GlobalVariable>(CS->getAggregateElement(1)->stripPointerCasts());
|
|
|
|
}
|
2015-04-01 06:35:44 +08:00
|
|
|
HT.Handler = cast<Function>(CH->getHandlerBlockOrFunc());
|
2015-04-04 06:49:05 +08:00
|
|
|
HT.CatchObjRecoverIdx = CH->getExceptionVarIndex();
|
2015-04-01 06:35:44 +08:00
|
|
|
TBME.HandlerArray.push_back(HT);
|
|
|
|
}
|
|
|
|
FuncInfo.TryBlockMap.push_back(TBME);
|
|
|
|
}
|
|
|
|
|
2015-03-31 06:58:10 +08:00
|
|
|
static void print_name(const Value *V) {
|
2015-03-31 07:14:45 +08:00
|
|
|
#ifndef NDEBUG
|
2015-03-31 06:58:10 +08:00
|
|
|
if (!V) {
|
|
|
|
DEBUG(dbgs() << "null");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const auto *F = dyn_cast<Function>(V))
|
|
|
|
DEBUG(dbgs() << F->getName());
|
|
|
|
else
|
|
|
|
DEBUG(V->dump());
|
2015-03-31 07:14:45 +08:00
|
|
|
#endif
|
2015-03-31 06:58:10 +08:00
|
|
|
}
|
|
|
|
|
2015-04-01 06:35:44 +08:00
|
|
|
void WinEHNumbering::processCallSite(ArrayRef<ActionHandler *> Actions,
|
|
|
|
ImmutableCallSite CS) {
|
2015-05-12 03:41:19 +08:00
|
|
|
DEBUG(dbgs() << "processCallSite (EH state = " << currentEHNumber()
|
|
|
|
<< ") for: ");
|
|
|
|
print_name(CS ? CS.getCalledValue() : nullptr);
|
|
|
|
DEBUG(dbgs() << '\n');
|
|
|
|
|
|
|
|
DEBUG(dbgs() << "HandlerStack: \n");
|
|
|
|
for (int I = 0, E = HandlerStack.size(); I < E; ++I) {
|
|
|
|
DEBUG(dbgs() << " ");
|
|
|
|
print_name(HandlerStack[I]->getHandlerBlockOrFunc());
|
|
|
|
DEBUG(dbgs() << '\n');
|
|
|
|
}
|
|
|
|
DEBUG(dbgs() << "Actions: \n");
|
|
|
|
for (int I = 0, E = Actions.size(); I < E; ++I) {
|
|
|
|
DEBUG(dbgs() << " ");
|
|
|
|
print_name(Actions[I]->getHandlerBlockOrFunc());
|
|
|
|
DEBUG(dbgs() << '\n');
|
|
|
|
}
|
2015-03-31 06:58:10 +08:00
|
|
|
int FirstMismatch = 0;
|
|
|
|
for (int E = std::min(HandlerStack.size(), Actions.size()); FirstMismatch < E;
|
|
|
|
++FirstMismatch) {
|
|
|
|
if (HandlerStack[FirstMismatch]->getHandlerBlockOrFunc() !=
|
|
|
|
Actions[FirstMismatch]->getHandlerBlockOrFunc())
|
|
|
|
break;
|
2015-05-12 03:41:19 +08:00
|
|
|
// Delete any actions that are already represented on the handler stack.
|
2015-03-31 06:58:10 +08:00
|
|
|
delete Actions[FirstMismatch];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Don't recurse while we are looping over the handler stack. Instead, defer
|
|
|
|
// the numbering of the catch handlers until we are done popping.
|
2015-04-01 06:35:44 +08:00
|
|
|
SmallVector<CatchHandler *, 4> PoppedCatches;
|
2015-03-31 06:58:10 +08:00
|
|
|
for (int I = HandlerStack.size() - 1; I >= FirstMismatch; --I) {
|
2015-04-01 06:35:44 +08:00
|
|
|
if (auto *CH = dyn_cast<CatchHandler>(HandlerStack.back())) {
|
|
|
|
PoppedCatches.push_back(CH);
|
|
|
|
} else {
|
|
|
|
// Delete cleanup handlers
|
|
|
|
delete HandlerStack.back();
|
|
|
|
}
|
2015-03-31 06:58:10 +08:00
|
|
|
HandlerStack.pop_back();
|
|
|
|
}
|
|
|
|
|
2015-04-01 06:35:44 +08:00
|
|
|
int TryHigh = NextState - 1;
|
|
|
|
int LastTryLowIdx = 0;
|
|
|
|
for (int I = 0, E = PoppedCatches.size(); I != E; ++I) {
|
|
|
|
CatchHandler *CH = PoppedCatches[I];
|
2015-05-12 03:41:19 +08:00
|
|
|
DEBUG(dbgs() << "Popped handler with state " << CH->getEHState() << "\n");
|
2015-04-01 06:35:44 +08:00
|
|
|
if (I + 1 == E || CH->getEHState() != PoppedCatches[I + 1]->getEHState()) {
|
|
|
|
int TryLow = CH->getEHState();
|
|
|
|
auto Handlers =
|
|
|
|
makeArrayRef(&PoppedCatches[LastTryLowIdx], I - LastTryLowIdx + 1);
|
2015-05-12 03:41:19 +08:00
|
|
|
DEBUG(dbgs() << "createTryBlockMapEntry(" << TryLow << ", " << TryHigh);
|
2015-05-12 04:45:11 +08:00
|
|
|
for (size_t J = 0; J < Handlers.size(); ++J) {
|
2015-05-12 03:41:19 +08:00
|
|
|
DEBUG(dbgs() << ", ");
|
|
|
|
print_name(Handlers[J]->getHandlerBlockOrFunc());
|
|
|
|
}
|
|
|
|
DEBUG(dbgs() << ")\n");
|
2015-04-01 06:35:44 +08:00
|
|
|
createTryBlockMapEntry(TryLow, TryHigh, Handlers);
|
|
|
|
LastTryLowIdx = I + 1;
|
|
|
|
}
|
|
|
|
}
|
2015-03-31 06:58:10 +08:00
|
|
|
|
2015-04-01 06:35:44 +08:00
|
|
|
for (CatchHandler *CH : PoppedCatches) {
|
2015-05-12 03:41:19 +08:00
|
|
|
if (auto *F = dyn_cast<Function>(CH->getHandlerBlockOrFunc())) {
|
|
|
|
DEBUG(dbgs() << "Assigning base state " << NextState << " to ");
|
|
|
|
print_name(F);
|
|
|
|
DEBUG(dbgs() << '\n');
|
|
|
|
FuncInfo.HandlerBaseState[F] = NextState;
|
|
|
|
DEBUG(dbgs() << "createUnwindMapEntry(" << currentEHNumber()
|
|
|
|
<< ", null)\n");
|
|
|
|
createUnwindMapEntry(currentEHNumber(), nullptr);
|
|
|
|
++NextState;
|
2015-04-01 06:35:44 +08:00
|
|
|
calculateStateNumbers(*F);
|
2015-05-12 03:41:19 +08:00
|
|
|
}
|
2015-04-01 06:35:44 +08:00
|
|
|
delete CH;
|
|
|
|
}
|
|
|
|
|
2015-05-12 03:41:19 +08:00
|
|
|
// The handler functions may have pushed actions onto the handler stack
|
|
|
|
// that we expected to push here. Compare the handler stack to our
|
|
|
|
// actions again to check for that possibility.
|
2015-05-12 04:45:11 +08:00
|
|
|
if (HandlerStack.size() > (size_t)FirstMismatch) {
|
2015-05-12 03:41:19 +08:00
|
|
|
for (int E = std::min(HandlerStack.size(), Actions.size());
|
|
|
|
FirstMismatch < E; ++FirstMismatch) {
|
|
|
|
if (HandlerStack[FirstMismatch]->getHandlerBlockOrFunc() !=
|
|
|
|
Actions[FirstMismatch]->getHandlerBlockOrFunc())
|
|
|
|
break;
|
|
|
|
delete Actions[FirstMismatch];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DEBUG(dbgs() << "Pushing actions for CallSite: ");
|
|
|
|
print_name(CS ? CS.getCalledValue() : nullptr);
|
|
|
|
DEBUG(dbgs() << '\n');
|
|
|
|
|
2015-04-01 06:35:44 +08:00
|
|
|
bool LastActionWasCatch = false;
|
2015-03-31 06:58:10 +08:00
|
|
|
for (size_t I = FirstMismatch; I != Actions.size(); ++I) {
|
2015-04-01 06:35:44 +08:00
|
|
|
// We can reuse eh states when pushing two catches for the same invoke.
|
|
|
|
bool CurrActionIsCatch = isa<CatchHandler>(Actions[I]);
|
|
|
|
// FIXME: Reenable this optimization!
|
|
|
|
if (CurrActionIsCatch && LastActionWasCatch && false) {
|
2015-05-12 03:41:19 +08:00
|
|
|
DEBUG(dbgs() << "setEHState for handler to " << currentEHNumber()
|
|
|
|
<< "\n");
|
2015-04-01 06:35:44 +08:00
|
|
|
Actions[I]->setEHState(currentEHNumber());
|
|
|
|
} else {
|
2015-05-12 03:41:19 +08:00
|
|
|
DEBUG(dbgs() << "createUnwindMapEntry(" << currentEHNumber() << ", ");
|
|
|
|
print_name(Actions[I]->getHandlerBlockOrFunc());
|
|
|
|
DEBUG(dbgs() << ")\n");
|
2015-04-01 06:35:44 +08:00
|
|
|
createUnwindMapEntry(currentEHNumber(), Actions[I]);
|
2015-05-12 03:41:19 +08:00
|
|
|
DEBUG(dbgs() << "setEHState for handler to " << NextState << "\n");
|
2015-04-01 06:35:44 +08:00
|
|
|
Actions[I]->setEHState(NextState);
|
|
|
|
NextState++;
|
|
|
|
}
|
2015-03-31 06:58:10 +08:00
|
|
|
HandlerStack.push_back(Actions[I]);
|
2015-04-01 06:35:44 +08:00
|
|
|
LastActionWasCatch = CurrActionIsCatch;
|
2015-03-31 06:58:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
DEBUG(dbgs() << "In EHState " << currentEHNumber() << " for CallSite: ");
|
|
|
|
print_name(CS ? CS.getCalledValue() : nullptr);
|
|
|
|
DEBUG(dbgs() << '\n');
|
|
|
|
}
|
|
|
|
|
|
|
|
void WinEHNumbering::calculateStateNumbers(const Function &F) {
|
2015-04-01 06:35:44 +08:00
|
|
|
auto I = VisitedHandlers.insert(&F);
|
|
|
|
if (!I.second)
|
|
|
|
return; // We've already visited this handler, don't renumber it.
|
|
|
|
|
2015-05-12 03:41:19 +08:00
|
|
|
int OldBaseState = CurrentBaseState;
|
|
|
|
if (FuncInfo.HandlerBaseState.count(&F)) {
|
|
|
|
CurrentBaseState = FuncInfo.HandlerBaseState[&F];
|
|
|
|
}
|
|
|
|
|
2015-03-31 06:58:10 +08:00
|
|
|
DEBUG(dbgs() << "Calculating state numbers for: " << F.getName() << '\n');
|
|
|
|
SmallVector<ActionHandler *, 4> ActionList;
|
|
|
|
for (const BasicBlock &BB : F) {
|
|
|
|
for (const Instruction &I : BB) {
|
|
|
|
const auto *CI = dyn_cast<CallInst>(&I);
|
|
|
|
if (!CI || CI->doesNotThrow())
|
|
|
|
continue;
|
2015-04-01 06:35:44 +08:00
|
|
|
processCallSite(None, CI);
|
2015-03-31 06:58:10 +08:00
|
|
|
}
|
|
|
|
const auto *II = dyn_cast<InvokeInst>(BB.getTerminator());
|
|
|
|
if (!II)
|
|
|
|
continue;
|
|
|
|
const LandingPadInst *LPI = II->getLandingPadInst();
|
2015-04-01 06:35:44 +08:00
|
|
|
auto *ActionsCall = dyn_cast<IntrinsicInst>(LPI->getNextNode());
|
|
|
|
if (!ActionsCall)
|
|
|
|
continue;
|
|
|
|
assert(ActionsCall->getIntrinsicID() == Intrinsic::eh_actions);
|
|
|
|
parseEHActions(ActionsCall, ActionList);
|
2015-05-12 03:41:19 +08:00
|
|
|
if (ActionList.empty())
|
|
|
|
continue;
|
2015-04-01 06:35:44 +08:00
|
|
|
processCallSite(ActionList, II);
|
|
|
|
ActionList.clear();
|
|
|
|
FuncInfo.LandingPadStateMap[LPI] = currentEHNumber();
|
2015-05-12 03:41:19 +08:00
|
|
|
DEBUG(dbgs() << "Assigning state " << currentEHNumber()
|
|
|
|
<< " to landing pad at " << LPI->getParent()->getName()
|
|
|
|
<< '\n');
|
2015-03-31 06:58:10 +08:00
|
|
|
}
|
2015-04-04 07:37:34 +08:00
|
|
|
|
|
|
|
FuncInfo.CatchHandlerMaxState[&F] = NextState - 1;
|
2015-05-12 03:41:19 +08:00
|
|
|
|
|
|
|
CurrentBaseState = OldBaseState;
|
2009-11-24 01:16:22 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// clear - Clear out all the function-specific state. This returns this
|
|
|
|
/// FunctionLoweringInfo to an empty state, ready to be used for a
|
|
|
|
/// different function.
|
|
|
|
void FunctionLoweringInfo::clear() {
|
2010-04-15 01:11:23 +08:00
|
|
|
assert(CatchInfoFound.size() == CatchInfoLost.size() &&
|
|
|
|
"Not all catch info was assigned to a landing pad!");
|
|
|
|
|
2009-11-24 01:16:22 +08:00
|
|
|
MBBMap.clear();
|
|
|
|
ValueMap.clear();
|
|
|
|
StaticAllocaMap.clear();
|
|
|
|
#ifndef NDEBUG
|
|
|
|
CatchInfoLost.clear();
|
|
|
|
CatchInfoFound.clear();
|
|
|
|
#endif
|
|
|
|
LiveOutRegInfo.clear();
|
2011-02-24 18:00:13 +08:00
|
|
|
VisitedBBs.clear();
|
2010-04-29 07:08:54 +08:00
|
|
|
ArgDbgValues.clear();
|
2010-09-01 06:22:42 +08:00
|
|
|
ByValArgFrameIndexMap.clear();
|
2010-07-10 17:00:22 +08:00
|
|
|
RegFixups.clear();
|
[Statepoints 3/4] Statepoint infrastructure for garbage collection: SelectionDAGBuilder
This is the third patch in a small series. It contains the CodeGen support for lowering the gc.statepoint intrinsic sequences (223078) to the STATEPOINT pseudo machine instruction (223085). The change also includes the set of helper routines and classes for working with gc.statepoints, gc.relocates, and gc.results since the lowering code uses them.
With this change, gc.statepoints should be functionally complete. The documentation will follow in the fourth change, and there will likely be some cleanup changes, but interested parties can start experimenting now.
I'm not particularly happy with the amount of code or complexity involved with the lowering step, but at least it's fairly well isolated. The statepoint lowering code is split into it's own files and anyone not working on the statepoint support itself should be able to ignore it.
During the lowering process, we currently spill aggressively to stack. This is not entirely ideal (and we have plans to do better), but it's functional, relatively straight forward, and matches closely the implementations of the patchpoint intrinsics. Most of the complexity comes from trying to keep relocated copies of values in the same stack slots across statepoints. Doing so avoids the insertion of pointless load and store instructions to reshuffle the stack. The current implementation isn't as effective as I'd like, but it is functional and 'good enough' for many common use cases.
In the long term, I'd like to figure out how to integrate the statepoint lowering with the register allocator. In principal, we shouldn't need to eagerly spill at all. The register allocator should do any spilling required and the statepoint should simply record that fact. Depending on how challenging that turns out to be, we may invest in a smarter global stack slot assignment mechanism as a stop gap measure.
Reviewed by: atrick, ributzka
llvm-svn: 223137
2014-12-03 02:50:36 +08:00
|
|
|
StatepointStackSlots.clear();
|
2014-09-24 11:22:56 +08:00
|
|
|
PreferredExtendType.clear();
|
2009-11-24 01:16:22 +08:00
|
|
|
}
|
|
|
|
|
2010-07-02 08:10:16 +08:00
|
|
|
/// CreateReg - Allocate a single virtual register for the given type.
|
2012-12-13 14:34:11 +08:00
|
|
|
unsigned FunctionLoweringInfo::CreateReg(MVT VT) {
|
2014-08-05 05:25:23 +08:00
|
|
|
return RegInfo->createVirtualRegister(
|
2014-10-09 08:57:31 +08:00
|
|
|
MF->getSubtarget().getTargetLowering()->getRegClassFor(VT));
|
2009-11-24 01:16:22 +08:00
|
|
|
}
|
|
|
|
|
2010-07-02 08:10:16 +08:00
|
|
|
/// CreateRegs - Allocate the appropriate number of virtual registers of
|
2009-11-24 01:16:22 +08:00
|
|
|
/// the correctly promoted or expanded types. Assign these registers
|
|
|
|
/// consecutive vreg numbers and return the first assigned number.
|
|
|
|
///
|
|
|
|
/// In the case that the given value has struct or array type, this function
|
|
|
|
/// will assign registers for each member or element.
|
|
|
|
///
|
2011-07-18 12:54:35 +08:00
|
|
|
unsigned FunctionLoweringInfo::CreateRegs(Type *Ty) {
|
2014-10-09 08:57:31 +08:00
|
|
|
const TargetLowering *TLI = MF->getSubtarget().getTargetLowering();
|
2013-06-20 04:32:16 +08:00
|
|
|
|
2009-11-24 01:16:22 +08:00
|
|
|
SmallVector<EVT, 4> ValueVTs;
|
2013-06-06 08:11:39 +08:00
|
|
|
ComputeValueVTs(*TLI, Ty, ValueVTs);
|
2009-11-24 01:16:22 +08:00
|
|
|
|
|
|
|
unsigned FirstReg = 0;
|
|
|
|
for (unsigned Value = 0, e = ValueVTs.size(); Value != e; ++Value) {
|
|
|
|
EVT ValueVT = ValueVTs[Value];
|
2013-06-06 08:11:39 +08:00
|
|
|
MVT RegisterVT = TLI->getRegisterType(Ty->getContext(), ValueVT);
|
2009-11-24 01:16:22 +08:00
|
|
|
|
2013-06-06 08:11:39 +08:00
|
|
|
unsigned NumRegs = TLI->getNumRegisters(Ty->getContext(), ValueVT);
|
2009-11-24 01:16:22 +08:00
|
|
|
for (unsigned i = 0; i != NumRegs; ++i) {
|
2010-07-02 08:10:16 +08:00
|
|
|
unsigned R = CreateReg(RegisterVT);
|
2009-11-24 01:16:22 +08:00
|
|
|
if (!FirstReg) FirstReg = R;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return FirstReg;
|
|
|
|
}
|
2009-11-24 01:42:46 +08:00
|
|
|
|
2011-02-24 18:00:25 +08:00
|
|
|
/// GetLiveOutRegInfo - Gets LiveOutInfo for a register, returning NULL if the
|
|
|
|
/// register is a PHI destination and the PHI's LiveOutInfo is not valid. If
|
|
|
|
/// the register's LiveOutInfo is for a smaller bit width, it is extended to
|
|
|
|
/// the larger bit width by zero extension. The bit width must be no smaller
|
|
|
|
/// than the LiveOutInfo's existing bit width.
|
|
|
|
const FunctionLoweringInfo::LiveOutInfo *
|
|
|
|
FunctionLoweringInfo::GetLiveOutRegInfo(unsigned Reg, unsigned BitWidth) {
|
|
|
|
if (!LiveOutRegInfo.inBounds(Reg))
|
2014-04-14 08:51:57 +08:00
|
|
|
return nullptr;
|
2011-02-24 18:00:25 +08:00
|
|
|
|
|
|
|
LiveOutInfo *LOI = &LiveOutRegInfo[Reg];
|
|
|
|
if (!LOI->IsValid)
|
2014-04-14 08:51:57 +08:00
|
|
|
return nullptr;
|
2011-02-24 18:00:25 +08:00
|
|
|
|
2011-02-25 09:10:55 +08:00
|
|
|
if (BitWidth > LOI->KnownZero.getBitWidth()) {
|
2011-02-25 09:11:01 +08:00
|
|
|
LOI->NumSignBits = 1;
|
2011-02-24 18:00:25 +08:00
|
|
|
LOI->KnownZero = LOI->KnownZero.zextOrTrunc(BitWidth);
|
|
|
|
LOI->KnownOne = LOI->KnownOne.zextOrTrunc(BitWidth);
|
|
|
|
}
|
|
|
|
|
|
|
|
return LOI;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ComputePHILiveOutRegInfo - Compute LiveOutInfo for a PHI's destination
|
|
|
|
/// register based on the LiveOutInfo of its operands.
|
|
|
|
void FunctionLoweringInfo::ComputePHILiveOutRegInfo(const PHINode *PN) {
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty = PN->getType();
|
2011-02-24 18:00:25 +08:00
|
|
|
if (!Ty->isIntegerTy() || Ty->isVectorTy())
|
|
|
|
return;
|
|
|
|
|
|
|
|
SmallVector<EVT, 1> ValueVTs;
|
2013-06-06 08:11:39 +08:00
|
|
|
ComputeValueVTs(*TLI, Ty, ValueVTs);
|
2011-02-24 18:00:25 +08:00
|
|
|
assert(ValueVTs.size() == 1 &&
|
|
|
|
"PHIs with non-vector integer types should have a single VT.");
|
|
|
|
EVT IntVT = ValueVTs[0];
|
|
|
|
|
2013-06-06 08:11:39 +08:00
|
|
|
if (TLI->getNumRegisters(PN->getContext(), IntVT) != 1)
|
2011-02-24 18:00:25 +08:00
|
|
|
return;
|
2013-06-06 08:11:39 +08:00
|
|
|
IntVT = TLI->getTypeToTransformTo(PN->getContext(), IntVT);
|
2011-02-24 18:00:25 +08:00
|
|
|
unsigned BitWidth = IntVT.getSizeInBits();
|
|
|
|
|
|
|
|
unsigned DestReg = ValueMap[PN];
|
|
|
|
if (!TargetRegisterInfo::isVirtualRegister(DestReg))
|
|
|
|
return;
|
|
|
|
LiveOutRegInfo.grow(DestReg);
|
|
|
|
LiveOutInfo &DestLOI = LiveOutRegInfo[DestReg];
|
|
|
|
|
|
|
|
Value *V = PN->getIncomingValue(0);
|
|
|
|
if (isa<UndefValue>(V) || isa<ConstantExpr>(V)) {
|
|
|
|
DestLOI.NumSignBits = 1;
|
|
|
|
APInt Zero(BitWidth, 0);
|
|
|
|
DestLOI.KnownZero = Zero;
|
|
|
|
DestLOI.KnownOne = Zero;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
|
|
|
|
APInt Val = CI->getValue().zextOrTrunc(BitWidth);
|
|
|
|
DestLOI.NumSignBits = Val.getNumSignBits();
|
|
|
|
DestLOI.KnownZero = ~Val;
|
|
|
|
DestLOI.KnownOne = Val;
|
|
|
|
} else {
|
|
|
|
assert(ValueMap.count(V) && "V should have been placed in ValueMap when its"
|
|
|
|
"CopyToReg node was created.");
|
|
|
|
unsigned SrcReg = ValueMap[V];
|
|
|
|
if (!TargetRegisterInfo::isVirtualRegister(SrcReg)) {
|
|
|
|
DestLOI.IsValid = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const LiveOutInfo *SrcLOI = GetLiveOutRegInfo(SrcReg, BitWidth);
|
|
|
|
if (!SrcLOI) {
|
|
|
|
DestLOI.IsValid = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
DestLOI = *SrcLOI;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(DestLOI.KnownZero.getBitWidth() == BitWidth &&
|
|
|
|
DestLOI.KnownOne.getBitWidth() == BitWidth &&
|
|
|
|
"Masks should have the same bit width as the type.");
|
|
|
|
|
|
|
|
for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i) {
|
|
|
|
Value *V = PN->getIncomingValue(i);
|
|
|
|
if (isa<UndefValue>(V) || isa<ConstantExpr>(V)) {
|
|
|
|
DestLOI.NumSignBits = 1;
|
|
|
|
APInt Zero(BitWidth, 0);
|
|
|
|
DestLOI.KnownZero = Zero;
|
|
|
|
DestLOI.KnownOne = Zero;
|
2011-06-09 07:55:35 +08:00
|
|
|
return;
|
2011-02-24 18:00:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
|
|
|
|
APInt Val = CI->getValue().zextOrTrunc(BitWidth);
|
|
|
|
DestLOI.NumSignBits = std::min(DestLOI.NumSignBits, Val.getNumSignBits());
|
|
|
|
DestLOI.KnownZero &= ~Val;
|
|
|
|
DestLOI.KnownOne &= Val;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(ValueMap.count(V) && "V should have been placed in ValueMap when "
|
|
|
|
"its CopyToReg node was created.");
|
|
|
|
unsigned SrcReg = ValueMap[V];
|
|
|
|
if (!TargetRegisterInfo::isVirtualRegister(SrcReg)) {
|
|
|
|
DestLOI.IsValid = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const LiveOutInfo *SrcLOI = GetLiveOutRegInfo(SrcReg, BitWidth);
|
|
|
|
if (!SrcLOI) {
|
|
|
|
DestLOI.IsValid = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
DestLOI.NumSignBits = std::min(DestLOI.NumSignBits, SrcLOI->NumSignBits);
|
|
|
|
DestLOI.KnownZero &= SrcLOI->KnownZero;
|
|
|
|
DestLOI.KnownOne &= SrcLOI->KnownOne;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-09 06:59:09 +08:00
|
|
|
/// setArgumentFrameIndex - Record frame index for the byval
|
2010-09-01 06:22:42 +08:00
|
|
|
/// argument. This overrides previous frame index entry for this argument,
|
|
|
|
/// if any.
|
2011-09-09 06:59:09 +08:00
|
|
|
void FunctionLoweringInfo::setArgumentFrameIndex(const Argument *A,
|
2012-02-24 09:59:01 +08:00
|
|
|
int FI) {
|
2010-09-01 06:22:42 +08:00
|
|
|
ByValArgFrameIndexMap[A] = FI;
|
|
|
|
}
|
2011-06-09 07:55:35 +08:00
|
|
|
|
2011-09-09 06:59:09 +08:00
|
|
|
/// getArgumentFrameIndex - Get frame index for the byval argument.
|
2010-09-01 06:22:42 +08:00
|
|
|
/// If the argument does not have any assigned frame index then 0 is
|
|
|
|
/// returned.
|
2011-09-09 06:59:09 +08:00
|
|
|
int FunctionLoweringInfo::getArgumentFrameIndex(const Argument *A) {
|
2011-06-09 07:55:35 +08:00
|
|
|
DenseMap<const Argument *, int>::iterator I =
|
2010-09-01 06:22:42 +08:00
|
|
|
ByValArgFrameIndexMap.find(A);
|
|
|
|
if (I != ByValArgFrameIndexMap.end())
|
|
|
|
return I->second;
|
2012-02-23 11:39:43 +08:00
|
|
|
DEBUG(dbgs() << "Argument does not have assigned frame index!\n");
|
2010-09-01 06:22:42 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-02-23 03:06:13 +08:00
|
|
|
/// ComputeUsesVAFloatArgument - Determine if any floating-point values are
|
|
|
|
/// being passed to this variadic function, and set the MachineModuleInfo's
|
|
|
|
/// usesVAFloatArgument flag if so. This flag is used to emit an undefined
|
|
|
|
/// reference to _fltused on Windows, which will link in MSVCRT's
|
|
|
|
/// floating-point support.
|
|
|
|
void llvm::ComputeUsesVAFloatArgument(const CallInst &I,
|
|
|
|
MachineModuleInfo *MMI)
|
|
|
|
{
|
|
|
|
FunctionType *FT = cast<FunctionType>(
|
|
|
|
I.getCalledValue()->getType()->getContainedType(0));
|
|
|
|
if (FT->isVarArg() && !MMI->usesVAFloatArgument()) {
|
|
|
|
for (unsigned i = 0, e = I.getNumArgOperands(); i != e; ++i) {
|
|
|
|
Type* T = I.getArgOperand(i)->getType();
|
2015-04-16 01:41:42 +08:00
|
|
|
for (auto i : post_order(T)) {
|
2012-02-23 03:06:13 +08:00
|
|
|
if (i->isFloatingPointTy()) {
|
|
|
|
MMI->setUsesVAFloatArgument(true);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-18 05:56:44 +08:00
|
|
|
/// AddLandingPadInfo - Extract the exception handling information from the
|
|
|
|
/// landingpad instruction and add them to the specified machine module info.
|
|
|
|
void llvm::AddLandingPadInfo(const LandingPadInst &I, MachineModuleInfo &MMI,
|
|
|
|
MachineBasicBlock *MBB) {
|
|
|
|
MMI.addPersonality(MBB,
|
|
|
|
cast<Function>(I.getPersonalityFn()->stripPointerCasts()));
|
|
|
|
|
|
|
|
if (I.isCleanup())
|
|
|
|
MMI.addCleanup(MBB);
|
|
|
|
|
|
|
|
// FIXME: New EH - Add the clauses in reverse order. This isn't 100% correct,
|
|
|
|
// but we need to do it this way because of how the DWARF EH emitter
|
|
|
|
// processes the clauses.
|
|
|
|
for (unsigned i = I.getNumClauses(); i != 0; --i) {
|
|
|
|
Value *Val = I.getClause(i - 1);
|
|
|
|
if (I.isCatch(i - 1)) {
|
|
|
|
MMI.addCatchTypeInfo(MBB,
|
2014-11-14 08:35:50 +08:00
|
|
|
dyn_cast<GlobalValue>(Val->stripPointerCasts()));
|
2011-08-18 05:56:44 +08:00
|
|
|
} else {
|
|
|
|
// Add filters in a list.
|
|
|
|
Constant *CVal = cast<Constant>(Val);
|
2014-11-14 08:35:50 +08:00
|
|
|
SmallVector<const GlobalValue*, 4> FilterList;
|
2011-08-18 05:56:44 +08:00
|
|
|
for (User::op_iterator
|
|
|
|
II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II)
|
2014-11-14 08:35:50 +08:00
|
|
|
FilterList.push_back(cast<GlobalValue>((*II)->stripPointerCasts()));
|
2011-08-18 05:56:44 +08:00
|
|
|
|
|
|
|
MMI.addFilterTypeInfo(MBB, FilterList);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|