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
65 lines
2.2 KiB
C++
65 lines
2.2 KiB
C++
//===-- 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;
|
|
}
|