Skip to content

Commit

Permalink
[GlobalISel] Add basic Selector-emitter tblgen backend.
Browse files Browse the repository at this point in the history
This adds a basic tablegen backend that analyzes the SelectionDAG
patterns to find simple ones that are eligible for GlobalISel-emission.

That's similar to FastISel, with one notable difference: we're not fed
ISD opcodes, so we need to map the SDNode operators to generic opcodes.
That's done using GINodeEquiv in TargetGlobalISel.td.

Otherwise, this is mostly boilerplate, and lots of filtering of any kind
of "complicated" pattern. On AArch64, this is sufficient to match G_ADD
up to s64 (to ADDWrr/ADDXrr) and G_BR (to B).

Differential Revision: https://reviews.llvm.org/D26878

llvm-svn: 290284
  • Loading branch information
ahmedbougacha committed Dec 21, 2016
1 parent aa9fe53 commit 36f7035
Show file tree
Hide file tree
Showing 10 changed files with 446 additions and 7 deletions.
5 changes: 5 additions & 0 deletions llvm/include/llvm/Target/Target.td
Expand Up @@ -1340,3 +1340,8 @@ include "llvm/Target/TargetCallingConv.td"
// Pull in the common support for DAG isel generation.
//
include "llvm/Target/TargetSelectionDAG.td"

//===----------------------------------------------------------------------===//
// Pull in the common support for Global ISel generation.
//
include "llvm/Target/TargetGlobalISel.td"
29 changes: 29 additions & 0 deletions llvm/include/llvm/Target/TargetGlobalISel.td
@@ -0,0 +1,29 @@
//===- TargetGlobalISel.td - Common code for GlobalISel ----*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the target-independent interfaces used to support
// SelectionDAG instruction selection patterns (specified in
// TargetSelectionDAG.td) when generating GlobalISel instruction selectors.
//
// This is intended as a compatibility layer, to enable reuse of target
// descriptions written for SelectionDAG without requiring explicit GlobalISel
// support. It will eventually supersede SelectionDAG patterns.
//
//===----------------------------------------------------------------------===//

// Declare that a generic Instruction is 'equivalent' to an SDNode, that is,
// SelectionDAG patterns involving the SDNode can be transformed to match the
// Instruction instead.
class GINodeEquiv<Instruction i, SDNode node> {
Instruction I = i;
SDNode Node = node;
}

def : GINodeEquiv<G_ADD, add>;
def : GINodeEquiv<G_BR, br>;
12 changes: 6 additions & 6 deletions llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
Expand Up @@ -36,6 +36,8 @@ using namespace llvm;
#error "You shouldn't build this"
#endif

#include "AArch64GenGlobalISel.inc"

AArch64InstructionSelector::AArch64InstructionSelector(
const AArch64TargetMachine &TM, const AArch64Subtarget &STI,
const AArch64RegisterBankInfo &RBI)
Expand Down Expand Up @@ -139,6 +141,7 @@ static unsigned selectBinaryOp(unsigned GenericOpc, unsigned RegBankID,
case TargetOpcode::G_AND:
return AArch64::ANDWrr;
case TargetOpcode::G_ADD:
assert(OpSize != 32 && "s32 G_ADD should have been selected");
return AArch64::ADDWrr;
case TargetOpcode::G_SUB:
return AArch64::SUBWrr;
Expand All @@ -163,7 +166,6 @@ static unsigned selectBinaryOp(unsigned GenericOpc, unsigned RegBankID,
return AArch64::EORXrr;
case TargetOpcode::G_AND:
return AArch64::ANDXrr;
case TargetOpcode::G_ADD:
case TargetOpcode::G_GEP:
return AArch64::ADDXrr;
case TargetOpcode::G_SUB:
Expand Down Expand Up @@ -527,15 +529,13 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const {
return false;
}

if (selectImpl(I))
return true;

LLT Ty =
I.getOperand(0).isReg() ? MRI.getType(I.getOperand(0).getReg()) : LLT{};

switch (Opcode) {
case TargetOpcode::G_BR: {
I.setDesc(TII.get(AArch64::B));
return true;
}

case TargetOpcode::G_BRCOND: {
if (Ty.getSizeInBits() > 32) {
// We shouldn't need this on AArch64, but it would be implemented as an
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/AArch64/AArch64InstructionSelector.h
Expand Up @@ -32,6 +32,10 @@ class AArch64InstructionSelector : public InstructionSelector {
virtual bool select(MachineInstr &I) const override;

private:
/// tblgen-erated 'select' implementation, used as the initial selector for
/// the patterns that don't require complex C++.
bool selectImpl(MachineInstr &I) const;

const AArch64TargetMachine &TM;
const AArch64Subtarget &STI;
const AArch64InstrInfo &TII;
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/AArch64/CMakeLists.txt
Expand Up @@ -13,6 +13,9 @@ tablegen(LLVM AArch64GenCallingConv.inc -gen-callingconv)
tablegen(LLVM AArch64GenSubtargetInfo.inc -gen-subtarget)
tablegen(LLVM AArch64GenDisassemblerTables.inc -gen-disassembler)
tablegen(LLVM AArch64GenSystemOperands.inc -gen-searchable-tables)
if(LLVM_BUILD_GLOBAL_ISEL)
tablegen(LLVM AArch64GenGlobalISel.inc -gen-global-isel)
endif()

add_public_tablegen_target(AArch64CommonTableGen)

Expand Down
1 change: 1 addition & 0 deletions llvm/utils/TableGen/CMakeLists.txt
Expand Up @@ -22,6 +22,7 @@ add_tablegen(llvm-tblgen LLVM
DisassemblerEmitter.cpp
FastISelEmitter.cpp
FixedLenDecoderEmitter.cpp
GlobalISelEmitter.cpp
InstrInfoEmitter.cpp
IntrinsicEmitter.cpp
OptParserEmitter.cpp
Expand Down
2 changes: 2 additions & 0 deletions llvm/utils/TableGen/CodeGenDAGPatterns.h
Expand Up @@ -809,11 +809,13 @@ class CodeGenDAGPatterns {
LessRecordByID>::const_iterator pf_iterator;
pf_iterator pf_begin() const { return PatternFragments.begin(); }
pf_iterator pf_end() const { return PatternFragments.end(); }
iterator_range<pf_iterator> ptfs() const { return PatternFragments; }

// Patterns to match information.
typedef std::vector<PatternToMatch>::const_iterator ptm_iterator;
ptm_iterator ptm_begin() const { return PatternsToMatch.begin(); }
ptm_iterator ptm_end() const { return PatternsToMatch.end(); }
iterator_range<ptm_iterator> ptms() const { return PatternsToMatch; }

/// Parse the Pattern for an instruction, and insert the result in DAGInsts.
typedef std::map<Record*, DAGInstruction, LessRecordByID> DAGInstMap;
Expand Down

0 comments on commit 36f7035

Please sign in to comment.