Skip to content

Commit

Permalink
[X86][GlobalISel] Add minimal call lowering support to the IRTranslator
Browse files Browse the repository at this point in the history
Summary:
    Add basic functionality to support call lowering for X86.
    Currently only supports functions which return void and take zero arguments.
    Inspired by commit 286573.

Reviewers: ab, qcolombet, t.p.northover

Subscribers: llvm-commits

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

llvm-svn: 286935
  • Loading branch information
Zvi Rackover committed Nov 15, 2016
1 parent 0637099 commit 76dbf26
Show file tree
Hide file tree
Showing 9 changed files with 229 additions and 2 deletions.
14 changes: 14 additions & 0 deletions llvm/lib/Target/X86/CMakeLists.txt
Expand Up @@ -12,6 +12,19 @@ tablegen(LLVM X86GenCallingConv.inc -gen-callingconv)
tablegen(LLVM X86GenSubtargetInfo.inc -gen-subtarget)
add_public_tablegen_target(X86CommonTableGen)

# Add GlobalISel files if the build option was enabled.
set(GLOBAL_ISEL_FILES
X86CallLowering.cpp
)

if(LLVM_BUILD_GLOBAL_ISEL)
set(GLOBAL_ISEL_BUILD_FILES ${GLOBAL_ISEL_FILES})
else()
set(GLOBAL_ISEL_BUILD_FILES "")
set(LLVM_OPTIONAL_SOURCES LLVMGlobalISel ${GLOBAL_ISEL_FILES})
endif()


set(sources
X86AsmPrinter.cpp
X86CallFrameOptimization.cpp
Expand Down Expand Up @@ -41,6 +54,7 @@ set(sources
X86VZeroUpper.cpp
X86WinAllocaExpander.cpp
X86WinEHState.cpp
${GLOBAL_ISEL_BUILD_FILES}
)

add_llvm_target(X86CodeGen ${sources})
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/X86/LLVMBuild.txt
Expand Up @@ -31,5 +31,5 @@ has_jit = 1
type = Library
name = X86CodeGen
parent = X86
required_libraries = Analysis AsmPrinter CodeGen Core MC SelectionDAG Support Target X86AsmPrinter X86Desc X86Info X86Utils
required_libraries = Analysis AsmPrinter CodeGen Core MC SelectionDAG Support Target X86AsmPrinter X86Desc X86Info X86Utils GlobalISel
add_to_library_groups = X86
46 changes: 46 additions & 0 deletions llvm/lib/Target/X86/X86CallLowering.cpp
@@ -0,0 +1,46 @@
//===-- llvm/lib/Target/X86/X86CallLowering.cpp - Call lowering -----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements the lowering of LLVM calls to machine code calls for
/// GlobalISel.
///
//===----------------------------------------------------------------------===//

#include "X86CallLowering.h"
#include "X86ISelLowering.h"
#include "X86InstrInfo.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"

using namespace llvm;

#ifndef LLVM_BUILD_GLOBAL_ISEL
#error "This shouldn't be built without GISel"
#endif

X86CallLowering::X86CallLowering(const X86TargetLowering &TLI)
: CallLowering(&TLI) {}

bool X86CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
const Value *Val, unsigned VReg) const {
// TODO: handle functions returning non-void values.
if (Val)
return false;

MIRBuilder.buildInstr(X86::RET).addImm(0);

return true;
}

bool X86CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
const Function &F,
ArrayRef<unsigned> VRegs) const {
// TODO: handle functions with one or more arguments.
return F.arg_empty();
}
39 changes: 39 additions & 0 deletions llvm/lib/Target/X86/X86CallLowering.h
@@ -0,0 +1,39 @@
//===-- llvm/lib/Target/X86/X86CallLowering.h - Call lowering -----===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file describes how to lower LLVM calls to machine code calls.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_X86_X86CALLLOWERING
#define LLVM_LIB_TARGET_X86_X86CALLLOWERING

#include "llvm/ADT/ArrayRef.h"
#include "llvm/CodeGen/GlobalISel/CallLowering.h"

namespace llvm {

class Function;
class MachineIRBuilder;
class X86TargetLowering;
class Value;

class X86CallLowering : public CallLowering {
public:
X86CallLowering(const X86TargetLowering &TLI);

bool lowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val,
unsigned VReg) const override;

bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F,
ArrayRef<unsigned> VRegs) const override;
};
} // End of namespace llvm;
#endif
20 changes: 20 additions & 0 deletions llvm/lib/Target/X86/X86Subtarget.cpp
Expand Up @@ -331,6 +331,26 @@ X86Subtarget::X86Subtarget(const Triple &TT, StringRef CPU, StringRef FS,
setPICStyle(PICStyles::GOT);
}

const CallLowering *X86Subtarget::getCallLowering() const {
assert(GISel && "Access to GlobalISel APIs not set");
return GISel->getCallLowering();
}

const InstructionSelector *X86Subtarget::getInstructionSelector() const {
assert(GISel && "Access to GlobalISel APIs not set");
return GISel->getInstructionSelector();
}

const LegalizerInfo *X86Subtarget::getLegalizerInfo() const {
assert(GISel && "Access to GlobalISel APIs not set");
return GISel->getLegalizerInfo();
}

const RegisterBankInfo *X86Subtarget::getRegBankInfo() const {
assert(GISel && "Access to GlobalISel APIs not set");
return GISel->getRegBankInfo();
}

bool X86Subtarget::enableEarlyIfConversion() const {
return hasCMov() && X86EarlyIfConv;
}
Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/Target/X86/X86Subtarget.h
Expand Up @@ -19,6 +19,7 @@
#include "X86InstrInfo.h"
#include "X86SelectionDAGInfo.h"
#include "llvm/ADT/Triple.h"
#include "llvm/CodeGen/GlobalISel/GISelAccessor.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/Target/TargetSubtargetInfo.h"
#include <string>
Expand Down Expand Up @@ -298,6 +299,10 @@ class X86Subtarget final : public X86GenSubtargetInfo {
/// Instruction itineraries for scheduling
InstrItineraryData InstrItins;

/// Gather the accessor points to GlobalISel-related APIs.
/// This is used to avoid ifndefs spreading around while GISel is
/// an optional library.
std::unique_ptr<GISelAccessor> GISel;
private:

/// Override the stack alignment.
Expand Down Expand Up @@ -326,6 +331,9 @@ class X86Subtarget final : public X86GenSubtargetInfo {
X86Subtarget(const Triple &TT, StringRef CPU, StringRef FS,
const X86TargetMachine &TM, unsigned StackAlignOverride);

/// This object will take onwership of \p GISelAccessor.
void setGISelAccessor(GISelAccessor &GISel) { this->GISel.reset(&GISel); }

const X86TargetLowering *getTargetLowering() const override {
return &TLInfo;
}
Expand Down Expand Up @@ -353,6 +361,11 @@ class X86Subtarget final : public X86GenSubtargetInfo {
/// subtarget options. Definition of function is auto generated by tblgen.
void ParseSubtargetFeatures(StringRef CPU, StringRef FS);

/// Methods used by Global ISel
const CallLowering *getCallLowering() const override;
const InstructionSelector *getInstructionSelector() const override;
const LegalizerInfo *getLegalizerInfo() const override;
const RegisterBankInfo *getRegBankInfo() const override;
private:
/// Initialize the full set of dependencies so we can use an initializer
/// list for X86Subtarget.
Expand Down
64 changes: 63 additions & 1 deletion llvm/lib/Target/X86/X86TargetMachine.cpp
Expand Up @@ -13,8 +13,11 @@

#include "X86TargetMachine.h"
#include "X86.h"
#include "X86CallLowering.h"
#include "X86TargetObjectFile.h"
#include "X86TargetTransformInfo.h"
#include "llvm/CodeGen/GlobalISel/GISelAccessor.h"
#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/Function.h"
Expand All @@ -39,6 +42,7 @@ extern "C" void LLVMInitializeX86Target() {
RegisterTargetMachine<X86TargetMachine> Y(getTheX86_64Target());

PassRegistry &PR = *PassRegistry::getPassRegistry();
initializeGlobalISel(PR);
initializeWinEHStatePassPass(PR);
initializeFixupBWInstPassPass(PR);
}
Expand Down Expand Up @@ -173,6 +177,29 @@ X86TargetMachine::X86TargetMachine(const Target &T, const Triple &TT,

X86TargetMachine::~X86TargetMachine() {}

#ifdef LLVM_BUILD_GLOBAL_ISEL
namespace {
struct X86GISelActualAccessor : public GISelAccessor {
std::unique_ptr<CallLowering> CL;
X86GISelActualAccessor(CallLowering* CL): CL(CL) {}
const CallLowering *getCallLowering() const override {
return CL.get();
}
const InstructionSelector *getInstructionSelector() const override {
//TODO: Implement
return nullptr;
}
const class LegalizerInfo *getLegalizerInfo() const override {
//TODO: Implement
return nullptr;
}
const RegisterBankInfo *getRegBankInfo() const override {
//TODO: Implement
return nullptr;
}
};
} // End anonymous namespace.
#endif
const X86Subtarget *
X86TargetMachine::getSubtargetImpl(const Function &F) const {
Attribute CPUAttr = F.getFnAttribute("target-cpu");
Expand Down Expand Up @@ -212,6 +239,13 @@ X86TargetMachine::getSubtargetImpl(const Function &F) const {
resetTargetOptions(F);
I = llvm::make_unique<X86Subtarget>(TargetTriple, CPU, FS, *this,
Options.StackAlignmentOverride);
#ifndef LLVM_BUILD_GLOBAL_ISEL
GISelAccessor *GISel = new GISelAccessor();
#else
X86GISelActualAccessor *GISel = new X86GISelActualAccessor(
new X86CallLowering(*I->getTargetLowering()));
#endif
I->setGISelAccessor(*GISel);
}
return I.get();
}
Expand Down Expand Up @@ -252,7 +286,13 @@ class X86PassConfig : public TargetPassConfig {

void addIRPasses() override;
bool addInstSelector() override;
bool addILPOpts() override;
#ifdef LLVM_BUILD_GLOBAL_ISEL
bool addIRTranslator() override;
bool addLegalizeMachineIR() override;
bool addRegBankSelect() override;
bool addGlobalInstructionSelect() override;
#endif
bool addILPOpts() override;
bool addPreISel() override;
void addPreRegAlloc() override;
void addPostRegAlloc() override;
Expand Down Expand Up @@ -287,6 +327,28 @@ bool X86PassConfig::addInstSelector() {
return false;
}

#ifdef LLVM_BUILD_GLOBAL_ISEL
bool X86PassConfig::addIRTranslator() {
addPass(new IRTranslator());
return false;
}

bool X86PassConfig::addLegalizeMachineIR() {
//TODO: Implement
return false;
}

bool X86PassConfig::addRegBankSelect() {
//TODO: Implement
return false;
}

bool X86PassConfig::addGlobalInstructionSelect() {
//TODO: Implement
return false;
}
#endif

bool X86PassConfig::addILPOpts() {
addPass(&EarlyIfConverterID);
if (EnableMachineCombinerPass)
Expand Down
31 changes: 31 additions & 0 deletions llvm/test/CodeGen/X86/GlobalISel/irtranslator-call.ll
@@ -0,0 +1,31 @@
; RUN: llc -mtriple i386 -global-isel -stop-after=irtranslator %s -o - | FileCheck %s
; RUN: llc -mtriple x86_64 -global-isel -stop-after=irtranslator %s -o - | FileCheck %s

define void @test_void_return() {
; CHECK-LABEL: name: test_void_return
; CHECK: alignment: 4
; CHECK-NEXT: exposesReturnsTwice: false
; CHECK-NEXT: legalized: false
; CHECK-NEXT: regBankSelected: false
; CHECK-NEXT: selected: false
; CHECK-NEXT: tracksRegLiveness: true
; CHECK-NEXT: frameInfo:
; CHECK-NEXT: isFrameAddressTaken: false
; CHECK-NEXT: isReturnAddressTaken: false
; CHECK-NEXT: hasStackMap: false
; CHECK-NEXT: hasPatchPoint: false
; CHECK-NEXT: stackSize: 0
; CHECK-NEXT: offsetAdjustment: 0
; CHECK-NEXT: maxAlignment: 0
; CHECK-NEXT: adjustsStack: false
; CHECK-NEXT: hasCalls: false
; CHECK-NEXT: maxCallFrameSize: 0
; CHECK-NEXT: hasOpaqueSPAdjustment: false
; CHECK-NEXT: hasVAStart: false
; CHECK-NEXT: hasMustTailInVarArgFunc: false
; CHECK-NEXT: body:
; CHECK-NEXT: bb.0:
; CHECK-NEXT: RET 0
entry:
ret void
}
2 changes: 2 additions & 0 deletions llvm/test/CodeGen/X86/GlobalISel/lit.local.cfg
@@ -0,0 +1,2 @@
if not 'global-isel' in config.root.available_features:
config.unsupported = True

0 comments on commit 76dbf26

Please sign in to comment.