forked from OSchip/llvm-project
parent
4b35e64504
commit
32a733e2c7
|
@ -258,6 +258,8 @@ private:
|
|||
|
||||
bool SelectGetElementPtr(User *I);
|
||||
|
||||
bool SelectCall(User *I);
|
||||
|
||||
bool SelectBitCast(User *I);
|
||||
|
||||
bool SelectCast(User *I, ISD::NodeType Opcode);
|
||||
|
|
|
@ -11,9 +11,13 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/GlobalVariable.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/IntrinsicInst.h"
|
||||
#include "llvm/CodeGen/FastISel.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
|
@ -260,6 +264,93 @@ bool FastISel::SelectGetElementPtr(User *I) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FastISel::SelectCall(User *I) {
|
||||
Function *F = cast<CallInst>(I)->getCalledFunction();
|
||||
if (!F) return false;
|
||||
|
||||
unsigned IID = F->getIntrinsicID();
|
||||
switch (IID) {
|
||||
default: break;
|
||||
case Intrinsic::dbg_stoppoint: {
|
||||
DbgStopPointInst *SPI = cast<DbgStopPointInst>(I);
|
||||
if (MMI && SPI->getContext() && MMI->Verify(SPI->getContext())) {
|
||||
DebugInfoDesc *DD = MMI->getDescFor(SPI->getContext());
|
||||
assert(DD && "Not a debug information descriptor");
|
||||
const CompileUnitDesc *CompileUnit = cast<CompileUnitDesc>(DD);
|
||||
unsigned SrcFile = MMI->RecordSource(CompileUnit);
|
||||
unsigned Line = SPI->getLine();
|
||||
unsigned Col = SPI->getColumn();
|
||||
unsigned ID = MMI->RecordSourceLine(Line, Col, SrcFile);
|
||||
const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
|
||||
BuildMI(MBB, II).addImm(ID);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case Intrinsic::dbg_region_start: {
|
||||
DbgRegionStartInst *RSI = cast<DbgRegionStartInst>(I);
|
||||
if (MMI && RSI->getContext() && MMI->Verify(RSI->getContext())) {
|
||||
unsigned ID = MMI->RecordRegionStart(RSI->getContext());
|
||||
const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
|
||||
BuildMI(MBB, II).addImm(ID);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case Intrinsic::dbg_region_end: {
|
||||
DbgRegionEndInst *REI = cast<DbgRegionEndInst>(I);
|
||||
if (MMI && REI->getContext() && MMI->Verify(REI->getContext())) {
|
||||
unsigned ID = MMI->RecordRegionEnd(REI->getContext());
|
||||
const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
|
||||
BuildMI(MBB, II).addImm(ID);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case Intrinsic::dbg_func_start: {
|
||||
if (!MMI) return true;
|
||||
DbgFuncStartInst *FSI = cast<DbgFuncStartInst>(I);
|
||||
Value *SP = FSI->getSubprogram();
|
||||
if (SP && MMI->Verify(SP)) {
|
||||
// llvm.dbg.func.start implicitly defines a dbg_stoppoint which is
|
||||
// what (most?) gdb expects.
|
||||
DebugInfoDesc *DD = MMI->getDescFor(SP);
|
||||
assert(DD && "Not a debug information descriptor");
|
||||
SubprogramDesc *Subprogram = cast<SubprogramDesc>(DD);
|
||||
const CompileUnitDesc *CompileUnit = Subprogram->getFile();
|
||||
unsigned SrcFile = MMI->RecordSource(CompileUnit);
|
||||
// Record the source line but does create a label. It will be emitted
|
||||
// at asm emission time.
|
||||
MMI->RecordSourceLine(Subprogram->getLine(), 0, SrcFile);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case Intrinsic::dbg_declare: {
|
||||
DbgDeclareInst *DI = cast<DbgDeclareInst>(I);
|
||||
Value *Variable = DI->getVariable();
|
||||
if (MMI && Variable && MMI->Verify(Variable)) {
|
||||
// Determine the address of the declared object.
|
||||
Value *Address = DI->getAddress();
|
||||
if (BitCastInst *BCI = dyn_cast<BitCastInst>(Address))
|
||||
Address = BCI->getOperand(0);
|
||||
AllocaInst *AI = dyn_cast<AllocaInst>(Address);
|
||||
// Don't handle byval struct arguments, for example.
|
||||
if (!AI) break;
|
||||
DenseMap<const AllocaInst*, int>::iterator SI =
|
||||
StaticAllocaMap.find(AI);
|
||||
assert(SI != StaticAllocaMap.end() && "Invalid dbg.declare!");
|
||||
int FI = SI->second;
|
||||
|
||||
// Determine the debug globalvariable.
|
||||
GlobalValue *GV = cast<GlobalVariable>(Variable);
|
||||
|
||||
// Build the DECLARE instruction.
|
||||
const TargetInstrDesc &II = TII.get(TargetInstrInfo::DECLARE);
|
||||
BuildMI(MBB, II).addFrameIndex(FI).addGlobalAddress(GV);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FastISel::SelectCast(User *I, ISD::NodeType Opcode) {
|
||||
MVT SrcVT = TLI.getValueType(I->getOperand(0)->getType());
|
||||
MVT DstVT = TLI.getValueType(I->getType());
|
||||
|
@ -424,6 +515,9 @@ FastISel::SelectOperator(User *I, unsigned Opcode) {
|
|||
// Dynamic-sized alloca is not handled yet.
|
||||
return false;
|
||||
|
||||
case Instruction::Call:
|
||||
return SelectCall(I);
|
||||
|
||||
case Instruction::BitCast:
|
||||
return SelectBitCast(I);
|
||||
|
||||
|
|
|
@ -246,7 +246,9 @@ static bool isUsedOutsideOfDefiningBlock(Instruction *I) {
|
|||
static bool isOnlyUsedInEntryBlock(Argument *A, bool EnableFastISel) {
|
||||
// With FastISel active, we may be splitting blocks, so force creation
|
||||
// of virtual registers for all non-dead arguments.
|
||||
if (EnableFastISel)
|
||||
// Don't force virtual registers for byval arguments though, because
|
||||
// fast-isel can't handle those in all cases.
|
||||
if (EnableFastISel && !A->hasByValAttr())
|
||||
return A->use_empty();
|
||||
|
||||
BasicBlock *Entry = A->getParent()->begin();
|
||||
|
|
|
@ -718,12 +718,27 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF,
|
|||
BasicBlock::iterator BI = Begin;
|
||||
|
||||
// Lower any arguments needed in this block if this is the entry block.
|
||||
if (LLVMBB == &Fn.getEntryBlock())
|
||||
bool SuppressFastISel = false;
|
||||
if (LLVMBB == &Fn.getEntryBlock()) {
|
||||
LowerArguments(LLVMBB);
|
||||
|
||||
// If any of the arguments has the byval attribute, forgo
|
||||
// fast-isel in the entry block.
|
||||
if (EnableFastISel) {
|
||||
unsigned j = 1;
|
||||
for (Function::arg_iterator I = Fn.arg_begin(), E = Fn.arg_end();
|
||||
I != E; ++I, ++j)
|
||||
if (Fn.paramHasAttr(j, ParamAttr::ByVal)) {
|
||||
cerr << "FastISel skips entry block due to byval argument";
|
||||
SuppressFastISel = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Before doing SelectionDAG ISel, see if FastISel has been requested.
|
||||
// FastISel doesn't support EH landing pads, which require special handling.
|
||||
if (EnableFastISel && !BB->isLandingPad()) {
|
||||
if (EnableFastISel && !SuppressFastISel && !BB->isLandingPad()) {
|
||||
if (FastISel *F = TLI.createFastISel(*FuncInfo->MF, MMI,
|
||||
FuncInfo->ValueMap,
|
||||
FuncInfo->MBBMap,
|
||||
|
@ -761,6 +776,9 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF,
|
|||
|
||||
// Then handle certain instructions as single-LLVM-Instruction blocks.
|
||||
if (isa<CallInst>(BI)) {
|
||||
cerr << "FastISel missed call: ";
|
||||
BI->dump();
|
||||
|
||||
if (BI->getType() != Type::VoidTy) {
|
||||
unsigned &R = FuncInfo->ValueMap[BI];
|
||||
if (!R)
|
||||
|
|
Loading…
Reference in New Issue