forked from OSchip/llvm-project
[GlobalISel] Introduce InlineAsmLowering class
Summary: Similar to the CallLowering class used for lowering LLVM IR calls to MIR calls, we introduce a separate class for lowering LLVM IR inline asm to MIR INLINEASM. There is no functional change yet, all existing tests should pass. Reviewers: arsenm, dsanders, aemerson, volkan, t.p.northover, paquette Reviewed By: aemerson Subscribers: gargaroff, wdng, mgorny, rovka, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D78316
This commit is contained in:
parent
61bccda9d9
commit
12030494fc
|
@ -235,7 +235,7 @@ private:
|
|||
bool translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
|
||||
MachineIRBuilder &MIRBuilder);
|
||||
|
||||
bool translateInlineAsm(const CallInst &CI, MachineIRBuilder &MIRBuilder);
|
||||
bool translateInlineAsm(const CallBase &CB, MachineIRBuilder &MIRBuilder);
|
||||
|
||||
/// Returns true if the value should be split into multiple LLTs.
|
||||
/// If \p Offsets is given then the split type's offsets will be stored in it.
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
//===- llvm/CodeGen/GlobalISel/InlineAsmLowering.h --------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// This file describes how to lower LLVM inline asm to machine code INLINEASM.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CODEGEN_GLOBALISEL_INLINEASMLOWERING_H
|
||||
#define LLVM_CODEGEN_GLOBALISEL_INLINEASMLOWERING_H
|
||||
|
||||
namespace llvm {
|
||||
class CallBase;
|
||||
class MachineIRBuilder;
|
||||
class TargetLowering;
|
||||
|
||||
class InlineAsmLowering {
|
||||
const TargetLowering *TLI;
|
||||
|
||||
virtual void anchor();
|
||||
|
||||
public:
|
||||
bool lowerInlineAsm(MachineIRBuilder &MIRBuilder, const CallBase &CB) const;
|
||||
|
||||
protected:
|
||||
/// Getter for generic TargetLowering class.
|
||||
const TargetLowering *getTLI() const { return TLI; }
|
||||
|
||||
/// Getter for target specific TargetLowering class.
|
||||
template <class XXXTargetLowering> const XXXTargetLowering *getTLI() const {
|
||||
return static_cast<const XXXTargetLowering *>(TLI);
|
||||
}
|
||||
|
||||
public:
|
||||
InlineAsmLowering(const TargetLowering *TLI) : TLI(TLI) {}
|
||||
virtual ~InlineAsmLowering() = default;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_CODEGEN_GLOBALISEL_INLINEASMLOWERING_H
|
|
@ -29,6 +29,7 @@
|
|||
namespace llvm {
|
||||
|
||||
class CallLowering;
|
||||
class InlineAsmLowering;
|
||||
class InstrItineraryData;
|
||||
struct InstrStage;
|
||||
class InstructionSelector;
|
||||
|
@ -102,6 +103,10 @@ public:
|
|||
}
|
||||
virtual const CallLowering *getCallLowering() const { return nullptr; }
|
||||
|
||||
virtual const InlineAsmLowering *getInlineAsmLowering() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// FIXME: This lets targets specialize the selector by subtarget (which lets
|
||||
// us do things like a dedicated avx512 selector). However, we might want
|
||||
// to also specialize selectors by MachineFunction, which would let us be
|
||||
|
|
|
@ -8,6 +8,7 @@ add_llvm_component_library(LLVMGlobalISel
|
|||
CombinerHelper.cpp
|
||||
GISelChangeObserver.cpp
|
||||
IRTranslator.cpp
|
||||
InlineAsmLowering.cpp
|
||||
InstructionSelect.cpp
|
||||
InstructionSelector.cpp
|
||||
LegalityPredicates.cpp
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "llvm/CodeGen/FunctionLoweringInfo.h"
|
||||
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
|
||||
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
|
||||
#include "llvm/CodeGen/GlobalISel/InlineAsmLowering.h"
|
||||
#include "llvm/CodeGen/LowLevelType.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
|
@ -1565,37 +1566,18 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool IRTranslator::translateInlineAsm(const CallInst &CI,
|
||||
bool IRTranslator::translateInlineAsm(const CallBase &CB,
|
||||
MachineIRBuilder &MIRBuilder) {
|
||||
const InlineAsm &IA = cast<InlineAsm>(*CI.getCalledValue());
|
||||
StringRef ConstraintStr = IA.getConstraintString();
|
||||
|
||||
bool HasOnlyMemoryClobber = false;
|
||||
if (!ConstraintStr.empty()) {
|
||||
// Until we have full inline assembly support, we just try to handle the
|
||||
// very simple case of just "~{memory}" to avoid falling back so often.
|
||||
if (ConstraintStr != "~{memory}")
|
||||
return false;
|
||||
HasOnlyMemoryClobber = true;
|
||||
const InlineAsmLowering *ALI = MF->getSubtarget().getInlineAsmLowering();
|
||||
|
||||
if (!ALI) {
|
||||
LLVM_DEBUG(
|
||||
dbgs() << "Inline asm lowering is not supported for this target yet\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned ExtraInfo = 0;
|
||||
if (IA.hasSideEffects())
|
||||
ExtraInfo |= InlineAsm::Extra_HasSideEffects;
|
||||
if (IA.getDialect() == InlineAsm::AD_Intel)
|
||||
ExtraInfo |= InlineAsm::Extra_AsmDialect;
|
||||
|
||||
// HACK: special casing for ~memory.
|
||||
if (HasOnlyMemoryClobber)
|
||||
ExtraInfo |= (InlineAsm::Extra_MayLoad | InlineAsm::Extra_MayStore);
|
||||
|
||||
auto Inst = MIRBuilder.buildInstr(TargetOpcode::INLINEASM)
|
||||
.addExternalSymbol(IA.getAsmString().c_str())
|
||||
.addImm(ExtraInfo);
|
||||
if (const MDNode *SrcLoc = CI.getMetadata("srcloc"))
|
||||
Inst.addMetadata(SrcLoc);
|
||||
|
||||
return true;
|
||||
return ALI->lowerInlineAsm(MIRBuilder, CB);
|
||||
}
|
||||
|
||||
bool IRTranslator::translateCallBase(const CallBase &CB,
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
//===-- lib/CodeGen/GlobalISel/InlineAsmLowering.cpp ----------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// This file implements the lowering from LLVM IR inline asm to MIR INLINEASM
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/CodeGen/GlobalISel/InlineAsmLowering.h"
|
||||
#include "llvm/CodeGen/Analysis.h"
|
||||
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
|
||||
#include "llvm/CodeGen/GlobalISel/Utils.h"
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/TargetLowering.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
|
||||
#define DEBUG_TYPE "inline-asm-lowering"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
void InlineAsmLowering::anchor() {}
|
||||
|
||||
bool InlineAsmLowering::lowerInlineAsm(MachineIRBuilder &MIRBuilder,
|
||||
const CallBase &Call) const {
|
||||
|
||||
const InlineAsm *IA = cast<InlineAsm>(Call.getCalledValue());
|
||||
StringRef ConstraintStr = IA->getConstraintString();
|
||||
|
||||
bool HasOnlyMemoryClobber = false;
|
||||
if (!ConstraintStr.empty()) {
|
||||
// Until we have full inline assembly support, we just try to handle the
|
||||
// very simple case of just "~{memory}" to avoid falling back so often.
|
||||
if (ConstraintStr != "~{memory}")
|
||||
return false;
|
||||
HasOnlyMemoryClobber = true;
|
||||
}
|
||||
|
||||
unsigned ExtraInfo = 0;
|
||||
if (IA->hasSideEffects())
|
||||
ExtraInfo |= InlineAsm::Extra_HasSideEffects;
|
||||
if (IA->getDialect() == InlineAsm::AD_Intel)
|
||||
ExtraInfo |= InlineAsm::Extra_AsmDialect;
|
||||
|
||||
// HACK: special casing for ~memory.
|
||||
if (HasOnlyMemoryClobber)
|
||||
ExtraInfo |= (InlineAsm::Extra_MayLoad | InlineAsm::Extra_MayStore);
|
||||
|
||||
auto Inst = MIRBuilder.buildInstr(TargetOpcode::INLINEASM)
|
||||
.addExternalSymbol(IA->getAsmString().c_str())
|
||||
.addImm(ExtraInfo);
|
||||
if (const MDNode *SrcLoc = Call.getMetadata("srcloc"))
|
||||
Inst.addMetadata(SrcLoc);
|
||||
|
||||
return true;
|
||||
}
|
|
@ -182,6 +182,7 @@ AArch64Subtarget::AArch64Subtarget(const Triple &TT, const std::string &CPU,
|
|||
ReserveXRegister.set(18);
|
||||
|
||||
CallLoweringInfo.reset(new AArch64CallLowering(*getTargetLowering()));
|
||||
InlineAsmLoweringInfo.reset(new InlineAsmLowering(getTargetLowering()));
|
||||
Legalizer.reset(new AArch64LegalizerInfo(*this));
|
||||
|
||||
auto *RBI = new AArch64RegisterBankInfo(*getRegisterInfo());
|
||||
|
@ -199,6 +200,10 @@ const CallLowering *AArch64Subtarget::getCallLowering() const {
|
|||
return CallLoweringInfo.get();
|
||||
}
|
||||
|
||||
const InlineAsmLowering *AArch64Subtarget::getInlineAsmLowering() const {
|
||||
return InlineAsmLoweringInfo.get();
|
||||
}
|
||||
|
||||
InstructionSelector *AArch64Subtarget::getInstructionSelector() const {
|
||||
return InstSelector.get();
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "AArch64RegisterInfo.h"
|
||||
#include "AArch64SelectionDAGInfo.h"
|
||||
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
|
||||
#include "llvm/CodeGen/GlobalISel/InlineAsmLowering.h"
|
||||
#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
|
||||
#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
|
||||
#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
|
||||
|
@ -233,6 +234,7 @@ protected:
|
|||
|
||||
/// GlobalISel related APIs.
|
||||
std::unique_ptr<CallLowering> CallLoweringInfo;
|
||||
std::unique_ptr<InlineAsmLowering> InlineAsmLoweringInfo;
|
||||
std::unique_ptr<InstructionSelector> InstSelector;
|
||||
std::unique_ptr<LegalizerInfo> Legalizer;
|
||||
std::unique_ptr<RegisterBankInfo> RegBankInfo;
|
||||
|
@ -268,6 +270,7 @@ public:
|
|||
return &getInstrInfo()->getRegisterInfo();
|
||||
}
|
||||
const CallLowering *getCallLowering() const override;
|
||||
const InlineAsmLowering *getInlineAsmLowering() const override;
|
||||
InstructionSelector *getInstructionSelector() const override;
|
||||
const LegalizerInfo *getLegalizerInfo() const override;
|
||||
const RegisterBankInfo *getRegBankInfo() const override;
|
||||
|
|
Loading…
Reference in New Issue