forked from OSchip/llvm-project
[X86][GlobalISel] Add minimal call lowering support to the IRTranslator
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
This commit is contained in:
parent
0637099f24
commit
76dbf26599
|
@ -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
|
||||
|
@ -41,6 +54,7 @@ set(sources
|
|||
X86VZeroUpper.cpp
|
||||
X86WinAllocaExpander.cpp
|
||||
X86WinEHState.cpp
|
||||
${GLOBAL_ISEL_BUILD_FILES}
|
||||
)
|
||||
|
||||
add_llvm_target(X86CodeGen ${sources})
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
@ -298,6 +299,10 @@ protected:
|
|||
/// 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.
|
||||
|
@ -326,6 +331,9 @@ public:
|
|||
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;
|
||||
}
|
||||
|
@ -353,6 +361,11 @@ public:
|
|||
/// 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.
|
||||
|
|
|
@ -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"
|
||||
|
@ -39,6 +42,7 @@ extern "C" void LLVMInitializeX86Target() {
|
|||
RegisterTargetMachine<X86TargetMachine> Y(getTheX86_64Target());
|
||||
|
||||
PassRegistry &PR = *PassRegistry::getPassRegistry();
|
||||
initializeGlobalISel(PR);
|
||||
initializeWinEHStatePassPass(PR);
|
||||
initializeFixupBWInstPassPass(PR);
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -252,7 +286,13 @@ public:
|
|||
|
||||
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;
|
||||
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
if not 'global-isel' in config.root.available_features:
|
||||
config.unsupported = True
|
Loading…
Reference in New Issue