aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff options
context:
space:
mode:
authorEli Bendersky <eliben@chromium.org>2013-07-15 16:09:15 -0700
committerEli Bendersky <eliben@chromium.org>2013-07-15 16:09:15 -0700
commitc6cf05cb5108f356dde97c01ee4188b0671d4542 (patch)
tree436fdc2a55296d3c202e7ef11f31be3be53efb5f /lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
parentc75199c649c739aade160289d93f257edc798cde (diff)
parent7dfcb84fc16b3bf6b2379713b53090757f0a45f9 (diff)
Merge commit '7dfcb84fc16b3bf6b2379713b53090757f0a45f9'
Conflicts: docs/LangRef.rst include/llvm/CodeGen/CallingConvLower.h include/llvm/IRReader/IRReader.h include/llvm/Target/TargetMachine.h lib/CodeGen/CallingConvLower.cpp lib/IRReader/IRReader.cpp lib/IRReader/LLVMBuild.txt lib/IRReader/Makefile lib/LLVMBuild.txt lib/Makefile lib/Support/MemoryBuffer.cpp lib/Support/Unix/PathV2.inc lib/Target/ARM/ARMBaseInstrInfo.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/ARMSubtarget.cpp lib/Target/ARM/ARMTargetMachine.cpp lib/Target/Mips/CMakeLists.txt lib/Target/Mips/MipsDelaySlotFiller.cpp lib/Target/Mips/MipsISelLowering.cpp lib/Target/Mips/MipsInstrInfo.td lib/Target/Mips/MipsSubtarget.cpp lib/Target/Mips/MipsSubtarget.h lib/Target/X86/X86FastISel.cpp lib/Target/X86/X86ISelDAGToDAG.cpp lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrControl.td lib/Target/X86/X86InstrFormats.td lib/Transforms/IPO/ExtractGV.cpp lib/Transforms/InstCombine/InstCombineCompares.cpp lib/Transforms/Utils/SimplifyLibCalls.cpp test/CodeGen/X86/fast-isel-divrem.ll test/MC/ARM/data-in-code.ll tools/Makefile tools/llvm-extract/llvm-extract.cpp tools/llvm-link/CMakeLists.txt tools/opt/CMakeLists.txt tools/opt/LLVMBuild.txt tools/opt/Makefile tools/opt/opt.cpp
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp175
1 files changed, 51 insertions, 124 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 1dcd6cdf2c..02b838234d 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -58,18 +58,21 @@
#include <algorithm>
using namespace llvm;
+STATISTIC(NumFastIselFailures, "Number of instructions fast isel failed on");
+STATISTIC(NumFastIselSuccess, "Number of instructions fast isel selected");
STATISTIC(NumFastIselBlocks, "Number of blocks selected entirely by fast isel");
STATISTIC(NumDAGBlocks, "Number of blocks selected using DAG");
-
-#ifndef NDEBUG
STATISTIC(NumDAGIselRetries,"Number of times dag isel has to try another path");
-STATISTIC(NumFastIselFailures, "Number of instructions fast isel failed on");
-STATISTIC(NumFastIselSuccess, "Number of instructions fast isel selected");
+STATISTIC(NumEntryBlocks, "Number of entry blocks encountered");
+STATISTIC(NumFastIselFailLowerArguments,
+ "Number of entry blocks where fast isel failed to lower arguments");
+#ifndef NDEBUG
static cl::opt<bool>
EnableFastISelVerbose2("fast-isel-verbose2", cl::Hidden,
cl::desc("Enable extra verbose messages in the \"fast\" "
"instruction selector"));
+
// Terminators
STATISTIC(NumFastIselFailRet,"Fast isel fails on Ret");
STATISTIC(NumFastIselFailBr,"Fast isel fails on Br");
@@ -363,6 +366,7 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
TargetSubtargetInfo &ST =
const_cast<TargetSubtargetInfo&>(TM.getSubtarget<TargetSubtargetInfo>());
ST.resetSubtargetFeatures(MF);
+ TM.resetTargetOptions(MF);
DEBUG(dbgs() << "\n\n\n=== " << Fn.getName() << "\n");
@@ -734,7 +738,7 @@ public:
} // end anonymous namespace
void SelectionDAGISel::DoInstructionSelection() {
- DEBUG(errs() << "===== Instruction selection begins: BB#"
+ DEBUG(dbgs() << "===== Instruction selection begins: BB#"
<< FuncInfo->MBB->getNumber()
<< " '" << FuncInfo->MBB->getName() << "'\n");
@@ -777,8 +781,12 @@ void SelectionDAGISel::DoInstructionSelection() {
if (ResNode == Node || Node->getOpcode() == ISD::DELETED_NODE)
continue;
// Replace node.
- if (ResNode)
+ if (ResNode) {
+ // Propagate ordering
+ CurDAG->AssignOrdering(ResNode, CurDAG->GetOrdering(Node));
+
ReplaceUses(Node, ResNode);
+ }
// If after the replacement this node is not used any more,
// remove this dead node.
@@ -789,7 +797,7 @@ void SelectionDAGISel::DoInstructionSelection() {
CurDAG->setRoot(Dummy.getValue());
}
- DEBUG(errs() << "===== Instruction selection ends:\n");
+ DEBUG(dbgs() << "===== Instruction selection ends:\n");
PostprocessISelDAG();
}
@@ -819,84 +827,6 @@ void SelectionDAGISel::PrepareEHLandingPad() {
if (Reg) MBB->addLiveIn(Reg);
}
-/// TryToFoldFastISelLoad - We're checking to see if we can fold the specified
-/// load into the specified FoldInst. Note that we could have a sequence where
-/// multiple LLVM IR instructions are folded into the same machineinstr. For
-/// example we could have:
-/// A: x = load i32 *P
-/// B: y = icmp A, 42
-/// C: br y, ...
-///
-/// In this scenario, LI is "A", and FoldInst is "C". We know about "B" (and
-/// any other folded instructions) because it is between A and C.
-///
-/// If we succeed in folding the load into the operation, return true.
-///
-bool SelectionDAGISel::TryToFoldFastISelLoad(const LoadInst *LI,
- const Instruction *FoldInst,
- FastISel *FastIS) {
- // We know that the load has a single use, but don't know what it is. If it
- // isn't one of the folded instructions, then we can't succeed here. Handle
- // this by scanning the single-use users of the load until we get to FoldInst.
- unsigned MaxUsers = 6; // Don't scan down huge single-use chains of instrs.
-
- const Instruction *TheUser = LI->use_back();
- while (TheUser != FoldInst && // Scan up until we find FoldInst.
- // Stay in the right block.
- TheUser->getParent() == FoldInst->getParent() &&
- --MaxUsers) { // Don't scan too far.
- // If there are multiple or no uses of this instruction, then bail out.
- if (!TheUser->hasOneUse())
- return false;
-
- TheUser = TheUser->use_back();
- }
-
- // If we didn't find the fold instruction, then we failed to collapse the
- // sequence.
- if (TheUser != FoldInst)
- return false;
-
- // Don't try to fold volatile loads. Target has to deal with alignment
- // constraints.
- if (LI->isVolatile()) return false;
-
- // Figure out which vreg this is going into. If there is no assigned vreg yet
- // then there actually was no reference to it. Perhaps the load is referenced
- // by a dead instruction.
- unsigned LoadReg = FastIS->getRegForValue(LI);
- if (LoadReg == 0)
- return false;
-
- // Check to see what the uses of this vreg are. If it has no uses, or more
- // than one use (at the machine instr level) then we can't fold it.
- MachineRegisterInfo::reg_iterator RI = RegInfo->reg_begin(LoadReg);
- if (RI == RegInfo->reg_end())
- return false;
-
- // See if there is exactly one use of the vreg. If there are multiple uses,
- // then the instruction got lowered to multiple machine instructions or the
- // use of the loaded value ended up being multiple operands of the result, in
- // either case, we can't fold this.
- MachineRegisterInfo::reg_iterator PostRI = RI; ++PostRI;
- if (PostRI != RegInfo->reg_end())
- return false;
-
- assert(RI.getOperand().isUse() &&
- "The only use of the vreg must be a use, we haven't emitted the def!");
-
- MachineInstr *User = &*RI;
-
- // Set the insertion point properly. Folding the load can cause generation of
- // other random instructions (like sign extends) for addressing modes, make
- // sure they get inserted in a logical place before the new instruction.
- FuncInfo->InsertPt = User;
- FuncInfo->MBB = User->getParent();
-
- // Ask the target to try folding the load.
- return FastIS->TryToFoldLoad(User, RI.getOperandNo(), LI);
-}
-
/// isFoldedOrDeadInstruction - Return true if the specified instruction is
/// side-effect free and is either dead or folded into a generated instruction.
/// Return false if it needs to be emitted.
@@ -1024,13 +954,11 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
FuncInfo->VisitedBBs.insert(LLVMBB);
}
- FuncInfo->MBB = FuncInfo->MBBMap[LLVMBB];
- FuncInfo->InsertPt = FuncInfo->MBB->getFirstNonPHI();
-
BasicBlock::const_iterator const Begin = LLVMBB->getFirstNonPHI();
BasicBlock::const_iterator const End = LLVMBB->end();
BasicBlock::const_iterator BI = End;
+ FuncInfo->MBB = FuncInfo->MBBMap[LLVMBB];
FuncInfo->InsertPt = FuncInfo->MBB->getFirstNonPHI();
// Setup an EH landing-pad block.
@@ -1044,17 +972,17 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
// Emit code for any incoming arguments. This must happen before
// beginning FastISel on the entry block.
if (LLVMBB == &Fn.getEntryBlock()) {
+ ++NumEntryBlocks;
+
// Lower any arguments needed in this block if this is the entry block.
if (!FastIS->LowerArguments()) {
-
+ // Fast isel failed to lower these arguments
+ ++NumFastIselFailLowerArguments;
if (EnableFastISelAbortArgs)
- // The "fast" selector couldn't lower these arguments. For the
- // purpose of debugging, just abort.
llvm_unreachable("FastISel didn't lower all arguments");
- // Call target indepedent SDISel argument lowering code if the target
- // specific routine is not successful.
- LowerArguments(LLVMBB);
+ // Use SelectionDAG argument lowering
+ LowerArguments(Fn);
CurDAG->setRoot(SDB->getControlRoot());
SDB->clear();
CodeGenAndEmitDAG();
@@ -1087,7 +1015,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
// Try to select the instruction with FastISel.
if (FastIS->SelectInstruction(Inst)) {
--NumFastIselRemaining;
- DEBUG(++NumFastIselSuccess);
+ ++NumFastIselSuccess;
// If fast isel succeeded, skip over all the folded instructions, and
// then see if there is a load right before the selected instructions.
// Try to fold the load if so.
@@ -1099,11 +1027,11 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
}
if (BeforeInst != Inst && isa<LoadInst>(BeforeInst) &&
BeforeInst->hasOneUse() &&
- TryToFoldFastISelLoad(cast<LoadInst>(BeforeInst), Inst, FastIS)) {
+ FastIS->tryToFoldLoad(cast<LoadInst>(BeforeInst), Inst)) {
// If we succeeded, don't re-select the load.
BI = llvm::next(BasicBlock::const_iterator(BeforeInst));
--NumFastIselRemaining;
- DEBUG(++NumFastIselSuccess);
+ ++NumFastIselSuccess;
}
continue;
}
@@ -1142,21 +1070,20 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
// Recompute NumFastIselRemaining as Selection DAG instruction
// selection may have handled the call, input args, etc.
unsigned RemainingNow = std::distance(Begin, BI);
- (void) RemainingNow;
- DEBUG(NumFastIselFailures += NumFastIselRemaining - RemainingNow);
- DEBUG(NumFastIselRemaining = RemainingNow);
+ NumFastIselFailures += NumFastIselRemaining - RemainingNow;
+ NumFastIselRemaining = RemainingNow;
continue;
}
if (isa<TerminatorInst>(Inst) && !isa<BranchInst>(Inst)) {
// Don't abort, and use a different message for terminator misses.
- DEBUG(NumFastIselFailures += NumFastIselRemaining);
+ NumFastIselFailures += NumFastIselRemaining;
if (EnableFastISelVerbose || EnableFastISelAbort) {
dbgs() << "FastISel missed terminator: ";
Inst->dump();
}
} else {
- DEBUG(NumFastIselFailures += NumFastIselRemaining);
+ NumFastIselFailures += NumFastIselRemaining;
if (EnableFastISelVerbose || EnableFastISelAbort) {
dbgs() << "FastISel miss: ";
Inst->dump();
@@ -1172,8 +1099,10 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
FastIS->recomputeInsertPt();
} else {
// Lower any arguments needed in this block if this is the entry block.
- if (LLVMBB == &Fn.getEntryBlock())
- LowerArguments(LLVMBB);
+ if (LLVMBB == &Fn.getEntryBlock()) {
+ ++NumEntryBlocks;
+ LowerArguments(Fn);
+ }
}
if (Begin != BI)
@@ -1668,9 +1597,7 @@ SDNode *SelectionDAGISel::Select_INLINEASM(SDNode *N) {
std::vector<SDValue> Ops(N->op_begin(), N->op_end());
SelectInlineAsmMemoryOperands(Ops);
- std::vector<EVT> VTs;
- VTs.push_back(MVT::Other);
- VTs.push_back(MVT::Glue);
+ EVT VTs[] = { MVT::Other, MVT::Glue };
SDValue New = CurDAG->getNode(ISD::INLINEASM, N->getDebugLoc(),
VTs, &Ops[0], Ops.size());
New->setNodeId(-1);
@@ -1767,7 +1694,7 @@ UpdateChainsAndGlue(SDNode *NodeToMatch, SDValue InputChain,
if (!NowDeadNodes.empty())
CurDAG->RemoveDeadNodes(NowDeadNodes);
- DEBUG(errs() << "ISEL: Match complete!\n");
+ DEBUG(dbgs() << "ISEL: Match complete!\n");
}
enum ChainResult {
@@ -2272,9 +2199,9 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
SmallVector<SDNode*, 3> ChainNodesMatched;
SmallVector<SDNode*, 3> GlueResultNodesMatched;
- DEBUG(errs() << "ISEL: Starting pattern match on root node: ";
+ DEBUG(dbgs() << "ISEL: Starting pattern match on root node: ";
NodeToMatch->dump(CurDAG);
- errs() << '\n');
+ dbgs() << '\n');
// Determine where to start the interpreter. Normally we start at opcode #0,
// but if the state machine starts with an OPC_SwitchOpcode, then we
@@ -2286,7 +2213,7 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
// Already computed the OpcodeOffset table, just index into it.
if (N.getOpcode() < OpcodeOffset.size())
MatcherIndex = OpcodeOffset[N.getOpcode()];
- DEBUG(errs() << " Initial Opcode index to " << MatcherIndex << "\n");
+ DEBUG(dbgs() << " Initial Opcode index to " << MatcherIndex << "\n");
} else if (MatcherTable[0] == OPC_SwitchOpcode) {
// Otherwise, the table isn't computed, but the state machine does start
@@ -2353,10 +2280,10 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
if (!Result)
break;
- DEBUG(errs() << " Skipped scope entry (due to false predicate) at "
+ DEBUG(dbgs() << " Skipped scope entry (due to false predicate) at "
<< "index " << MatcherIndexOfPredicate
<< ", continuing at " << FailIndex << "\n");
- DEBUG(++NumDAGIselRetries);
+ ++NumDAGIselRetries;
// Otherwise, we know that this case of the Scope is guaranteed to fail,
// move to the next case.
@@ -2483,7 +2410,7 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
if (CaseSize == 0) break;
// Otherwise, execute the case we found.
- DEBUG(errs() << " OpcodeSwitch from " << SwitchStart
+ DEBUG(dbgs() << " OpcodeSwitch from " << SwitchStart
<< " to " << MatcherIndex << "\n");
continue;
}
@@ -2515,7 +2442,7 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
if (CaseSize == 0) break;
// Otherwise, execute the case we found.
- DEBUG(errs() << " TypeSwitch[" << EVT(CurNodeVT).getEVTString()
+ DEBUG(dbgs() << " TypeSwitch[" << EVT(CurNodeVT).getEVTString()
<< "] from " << SwitchStart << " to " << MatcherIndex<<'\n');
continue;
}
@@ -2604,11 +2531,11 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
SDValue Imm = RecordedNodes[RecNo].first;
if (Imm->getOpcode() == ISD::Constant) {
- int64_t Val = cast<ConstantSDNode>(Imm)->getZExtValue();
- Imm = CurDAG->getTargetConstant(Val, Imm.getValueType());
+ const ConstantInt *Val=cast<ConstantSDNode>(Imm)->getConstantIntValue();
+ Imm = CurDAG->getConstant(*Val, Imm.getValueType(), true);
} else if (Imm->getOpcode() == ISD::ConstantFP) {
const ConstantFP *Val=cast<ConstantFPSDNode>(Imm)->getConstantFPValue();
- Imm = CurDAG->getTargetConstantFP(*Val, Imm.getValueType());
+ Imm = CurDAG->getConstantFP(*Val, Imm.getValueType(), true);
}
RecordedNodes.push_back(std::make_pair(Imm, RecordedNodes[RecNo].second));
@@ -2783,7 +2710,7 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
// If this is a normal EmitNode command, just create the new node and
// add the results to the RecordedNodes list.
Res = CurDAG->getMachineNode(TargetOpc, NodeToMatch->getDebugLoc(),
- VTList, Ops.data(), Ops.size());
+ VTList, Ops);
// Add all the non-glue/non-chain results to the RecordedNodes list.
for (unsigned i = 0, e = VTs.size(); i != e; ++i) {
@@ -2859,9 +2786,9 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
->setMemRefs(MemRefs, MemRefs + NumMemRefs);
}
- DEBUG(errs() << " "
+ DEBUG(dbgs() << " "
<< (Opcode == OPC_MorphNodeTo ? "Morphed" : "Created")
- << " node: "; Res->dump(CurDAG); errs() << "\n");
+ << " node: "; Res->dump(CurDAG); dbgs() << "\n");
// If this was a MorphNodeTo then we're completely done!
if (Opcode == OPC_MorphNodeTo) {
@@ -2936,8 +2863,8 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
// If the code reached this point, then the match failed. See if there is
// another child to try in the current 'Scope', otherwise pop it until we
// find a case to check.
- DEBUG(errs() << " Match failed at index " << CurrentOpcodeIndex << "\n");
- DEBUG(++NumDAGIselRetries);
+ DEBUG(dbgs() << " Match failed at index " << CurrentOpcodeIndex << "\n");
+ ++NumDAGIselRetries;
while (1) {
if (MatchScopes.empty()) {
CannotYetSelect(NodeToMatch);
@@ -2956,7 +2883,7 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
MatchedMemRefs.resize(LastScope.NumMatchedMemRefs);
MatcherIndex = LastScope.FailIndex;
- DEBUG(errs() << " Continuing at " << MatcherIndex << "\n");
+ DEBUG(dbgs() << " Continuing at " << MatcherIndex << "\n");
InputChain = LastScope.InputChain;
InputGlue = LastScope.InputGlue;