mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-07-19 03:29:22 +00:00
initial step at adding a dag-to-dag isel for X86 backend. Patch contributed
by Evan Cheng! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24371 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
422b0cee7a
commit
c961eea6cb
@ -13,7 +13,7 @@ TARGET = X86
|
|||||||
BUILT_SOURCES = X86GenRegisterInfo.h.inc X86GenRegisterNames.inc \
|
BUILT_SOURCES = X86GenRegisterInfo.h.inc X86GenRegisterNames.inc \
|
||||||
X86GenRegisterInfo.inc X86GenInstrNames.inc \
|
X86GenRegisterInfo.inc X86GenInstrNames.inc \
|
||||||
X86GenInstrInfo.inc X86GenAsmWriter.inc \
|
X86GenInstrInfo.inc X86GenAsmWriter.inc \
|
||||||
X86GenAsmWriter1.inc
|
X86GenAsmWriter1.inc X86GenDAGISel.inc
|
||||||
|
|
||||||
include $(LEVEL)/Makefile.common
|
include $(LEVEL)/Makefile.common
|
||||||
|
|
||||||
|
163
lib/Target/X86/X86ISelDAGToDAG.cpp
Normal file
163
lib/Target/X86/X86ISelDAGToDAG.cpp
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
//===-- X86ISelPattern.cpp - A DAG pattern matching inst selector for X86 -===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file was developed by the Evan Cheng and is distributed under
|
||||||
|
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file defines a DAG pattern matching instruction selector for X86,
|
||||||
|
// converting from a legalized dag to a X86 dag.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "X86.h"
|
||||||
|
#include "X86Subtarget.h"
|
||||||
|
#include "X86ISelLowering.h"
|
||||||
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
|
#include "llvm/CodeGen/SelectionDAGISel.h"
|
||||||
|
#include "llvm/Target/TargetMachine.h"
|
||||||
|
#include "llvm/Support/Debug.h"
|
||||||
|
#include "llvm/ADT/Statistic.h"
|
||||||
|
using namespace llvm;
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Pattern Matcher Implementation
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
Statistic<>
|
||||||
|
NumFPKill("x86-codegen", "Number of FP_REG_KILL instructions added");
|
||||||
|
|
||||||
|
//===--------------------------------------------------------------------===//
|
||||||
|
/// ISel - X86 specific code to select X86 machine instructions for
|
||||||
|
/// SelectionDAG operations.
|
||||||
|
///
|
||||||
|
class X86DAGToDAGISel : public SelectionDAGISel {
|
||||||
|
/// ContainsFPCode - Every instruction we select that uses or defines a FP
|
||||||
|
/// register should set this to true.
|
||||||
|
bool ContainsFPCode;
|
||||||
|
|
||||||
|
/// X86Lowering - This object fully describes how to lower LLVM code to an
|
||||||
|
/// X86-specific SelectionDAG.
|
||||||
|
X86TargetLowering X86Lowering;
|
||||||
|
|
||||||
|
/// Subtarget - Keep a pointer to the X86Subtarget around so that we can
|
||||||
|
/// make the right decision when generating code for different targets.
|
||||||
|
const X86Subtarget *Subtarget;
|
||||||
|
public:
|
||||||
|
X86DAGToDAGISel(TargetMachine &TM)
|
||||||
|
: SelectionDAGISel(X86Lowering), X86Lowering(TM) {
|
||||||
|
Subtarget = &TM.getSubtarget<X86Subtarget>();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const char *getPassName() const {
|
||||||
|
return "X86 DAG->DAG Instruction Selection";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// InstructionSelectBasicBlock - This callback is invoked by
|
||||||
|
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
|
||||||
|
virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
|
||||||
|
|
||||||
|
// Include the pieces autogenerated from the target description.
|
||||||
|
#include "X86GenDAGISel.inc"
|
||||||
|
|
||||||
|
private:
|
||||||
|
SDOperand Select(SDOperand N);
|
||||||
|
|
||||||
|
/// getI16Imm - Return a target constant with the specified value, of type
|
||||||
|
/// i16.
|
||||||
|
inline SDOperand getI16Imm(unsigned Imm) {
|
||||||
|
return CurDAG->getTargetConstant(Imm, MVT::i16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// getI32Imm - Return a target constant with the specified value, of type
|
||||||
|
/// i32.
|
||||||
|
inline SDOperand getI32Imm(unsigned Imm) {
|
||||||
|
return CurDAG->getTargetConstant(Imm, MVT::i32);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// InstructionSelectBasicBlock - This callback is invoked by SelectionDAGISel
|
||||||
|
/// when it has created a SelectionDAG for us to codegen.
|
||||||
|
void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
||||||
|
DEBUG(BB->dump());
|
||||||
|
|
||||||
|
// Codegen the basic block.
|
||||||
|
DAG.setRoot(Select(DAG.getRoot()));
|
||||||
|
DAG.RemoveDeadNodes();
|
||||||
|
|
||||||
|
// Emit machine code to BB.
|
||||||
|
ScheduleAndEmitDAG(DAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDOperand X86DAGToDAGISel::Select(SDOperand Op) {
|
||||||
|
SDNode *N = Op.Val;
|
||||||
|
MVT::ValueType OpVT = Op.getValueType();
|
||||||
|
unsigned Opc;
|
||||||
|
|
||||||
|
if (N->getOpcode() >= ISD::BUILTIN_OP_END)
|
||||||
|
return Op; // Already selected.
|
||||||
|
|
||||||
|
switch (N->getOpcode()) {
|
||||||
|
default: break;
|
||||||
|
case ISD::Constant: {
|
||||||
|
switch (OpVT) {
|
||||||
|
default: assert(0 && "Cannot use constants of this type!");
|
||||||
|
case MVT::i1:
|
||||||
|
case MVT::i8: Opc = X86::MOV8ri; break;
|
||||||
|
case MVT::i16: Opc = X86::MOV16ri; break;
|
||||||
|
case MVT::i32: Opc = X86::MOV32ri; break;
|
||||||
|
}
|
||||||
|
unsigned CVal = cast<ConstantSDNode>(N)->getValue();
|
||||||
|
SDOperand Op1 = CurDAG->getTargetConstant(CVal, OpVT);
|
||||||
|
CurDAG->SelectNodeTo(N, Opc, OpVT, Op1);
|
||||||
|
return Op;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ISD::RET: {
|
||||||
|
SDOperand Chain = Select(N->getOperand(0)); // Token chain.
|
||||||
|
switch (N->getNumOperands()) {
|
||||||
|
default:
|
||||||
|
assert(0 && "Unknown return instruction!");
|
||||||
|
case 3:
|
||||||
|
assert(0 && "Not yet handled return instruction!");
|
||||||
|
break;
|
||||||
|
case 2: {
|
||||||
|
SDOperand Val = Select(N->getOperand(1));
|
||||||
|
switch (N->getOperand(1).getValueType()) {
|
||||||
|
default:
|
||||||
|
assert(0 && "All other types should have been promoted!!");
|
||||||
|
case MVT::i32:
|
||||||
|
Chain = CurDAG->getCopyToReg(Chain, X86::EAX, Val);
|
||||||
|
break;
|
||||||
|
case MVT::f32:
|
||||||
|
case MVT::f64:
|
||||||
|
assert(0 && "Not yet handled return instruction!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (X86Lowering.getBytesToPopOnReturn() == 0)
|
||||||
|
CurDAG->SelectNodeTo(N, X86::RET, MVT::Other, Chain);
|
||||||
|
else
|
||||||
|
CurDAG->SelectNodeTo(N, X86::RET, MVT::Other, Chain,
|
||||||
|
getI16Imm(X86Lowering.getBytesToPopOnReturn()));
|
||||||
|
|
||||||
|
return SDOperand(N, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SelectCode(Op);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// createX86ISelDag - This pass converts a legalized DAG into a
|
||||||
|
/// X86-specific DAG, ready for instruction scheduling.
|
||||||
|
///
|
||||||
|
FunctionPass *llvm::createX86ISelDag(TargetMachine &TM) {
|
||||||
|
return new X86DAGToDAGISel(TM);
|
||||||
|
}
|
@ -47,6 +47,9 @@ namespace {
|
|||||||
cl::location(X86ScalarSSE),
|
cl::location(X86ScalarSSE),
|
||||||
cl::init(false));
|
cl::init(false));
|
||||||
|
|
||||||
|
cl::opt<bool> EnableX86DAGDAG("enable-x86-dag-isel", cl::Hidden,
|
||||||
|
cl::desc("Enable DAG-to-DAG isel for X86"));
|
||||||
|
|
||||||
// FIXME: This should eventually be handled with target triples and
|
// FIXME: This should eventually be handled with target triples and
|
||||||
// subtarget support!
|
// subtarget support!
|
||||||
cl::opt<X86VectorEnum, true>
|
cl::opt<X86VectorEnum, true>
|
||||||
@ -124,7 +127,10 @@ bool X86TargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out,
|
|||||||
PM.add(createUnreachableBlockEliminationPass());
|
PM.add(createUnreachableBlockEliminationPass());
|
||||||
|
|
||||||
// Install an instruction selector.
|
// Install an instruction selector.
|
||||||
PM.add(createX86ISelPattern(*this));
|
if (EnableX86DAGDAG)
|
||||||
|
PM.add(createX86ISelDag(*this));
|
||||||
|
else
|
||||||
|
PM.add(createX86ISelPattern(*this));
|
||||||
|
|
||||||
// Run optional SSA-based machine code optimizations next...
|
// Run optional SSA-based machine code optimizations next...
|
||||||
if (!NoSSAPeephole)
|
if (!NoSSAPeephole)
|
||||||
@ -192,7 +198,10 @@ void X86JITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
|
|||||||
PM.add(createUnreachableBlockEliminationPass());
|
PM.add(createUnreachableBlockEliminationPass());
|
||||||
|
|
||||||
// Install an instruction selector.
|
// Install an instruction selector.
|
||||||
PM.add(createX86ISelPattern(TM));
|
if (EnableX86DAGDAG)
|
||||||
|
PM.add(createX86ISelDag(TM));
|
||||||
|
else
|
||||||
|
PM.add(createX86ISelPattern(TM));
|
||||||
|
|
||||||
// Run optional SSA-based machine code optimizations next...
|
// Run optional SSA-based machine code optimizations next...
|
||||||
if (!NoSSAPeephole)
|
if (!NoSSAPeephole)
|
||||||
|
Loading…
Reference in New Issue
Block a user