#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
#include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
#include "llvm/CodeGen/GlobalISel/InlineAsmLowering.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/LowLevelTypeUtils.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RuntimeLibcallUtil.h"
#include "llvm/CodeGen/StackProtector.h"
#include "llvm/CodeGen/SwitchLoweringUtils.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/CodeGenTypes/LowLevelType.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsAMDGPU.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Statepoint.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/InitializePasses.h"
#include "llvm/MC/MCContext.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetIntrinsicInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/MemoryOpRemark.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <iterator>
#include <optional>
#include <string>
#include <utility>
#include <vector>
#define DEBUG_TYPE …
usingnamespacellvm;
static cl::opt<bool>
EnableCSEInIRTranslator("enable-cse-in-irtranslator",
cl::desc("Should enable CSE in irtranslator"),
cl::Optional, cl::init(false));
char IRTranslator::ID = …;
INITIALIZE_PASS_BEGIN(IRTranslator, DEBUG_TYPE, "IRTranslator LLVM IR -> MI",
false, false)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(StackProtector)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_END(IRTranslator, DEBUG_TYPE, "IRTranslator LLVM IR -> MI",
false, false)
static void reportTranslationError(MachineFunction &MF,
const TargetPassConfig &TPC,
OptimizationRemarkEmitter &ORE,
OptimizationRemarkMissed &R) { … }
IRTranslator::IRTranslator(CodeGenOptLevel optlevel)
: … { … }
#ifndef NDEBUG
namespace {
class DILocationVerifier : public GISelChangeObserver {
const Instruction *CurrInst = nullptr;
public:
DILocationVerifier() = default;
~DILocationVerifier() = default;
const Instruction *getCurrentInst() const { return CurrInst; }
void setCurrentInst(const Instruction *Inst) { CurrInst = Inst; }
void erasingInstr(MachineInstr &MI) override {}
void changingInstr(MachineInstr &MI) override {}
void changedInstr(MachineInstr &MI) override {}
void createdInstr(MachineInstr &MI) override {
assert(getCurrentInst() && "Inserted instruction without a current MI");
#ifndef NDEBUG
LLVM_DEBUG(dbgs() << "Checking DILocation from " << *CurrInst
<< " was copied to " << MI);
#endif
assert((CurrInst->getDebugLoc() == MI.getDebugLoc() ||
(MI.getParent()->isEntryBlock() && !MI.getDebugLoc()) ||
(MI.isDebugInstr())) &&
"Line info was not transferred to all instructions");
}
};
}
#endif
void IRTranslator::getAnalysisUsage(AnalysisUsage &AU) const { … }
IRTranslator::ValueToVRegInfo::VRegListT &
IRTranslator::allocateVRegs(const Value &Val) { … }
ArrayRef<Register> IRTranslator::getOrCreateVRegs(const Value &Val) { … }
int IRTranslator::getOrCreateFrameIndex(const AllocaInst &AI) { … }
Align IRTranslator::getMemOpAlign(const Instruction &I) { … }
MachineBasicBlock &IRTranslator::getMBB(const BasicBlock &BB) { … }
void IRTranslator::addMachineCFGPred(CFGEdge Edge, MachineBasicBlock *NewPred) { … }
bool IRTranslator::translateBinaryOp(unsigned Opcode, const User &U,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateUnaryOp(unsigned Opcode, const User &U,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateFNeg(const User &U, MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateCompare(const User &U,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateRet(const User &U, MachineIRBuilder &MIRBuilder) { … }
void IRTranslator::emitBranchForMergedCondition(
const Value *Cond, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
MachineBasicBlock *CurBB, MachineBasicBlock *SwitchBB,
BranchProbability TProb, BranchProbability FProb, bool InvertCond) { … }
static bool isValInBlock(const Value *V, const BasicBlock *BB) { … }
void IRTranslator::findMergedConditions(
const Value *Cond, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
MachineBasicBlock *CurBB, MachineBasicBlock *SwitchBB,
Instruction::BinaryOps Opc, BranchProbability TProb,
BranchProbability FProb, bool InvertCond) { … }
bool IRTranslator::shouldEmitAsBranches(
const std::vector<SwitchCG::CaseBlock> &Cases) { … }
bool IRTranslator::translateBr(const User &U, MachineIRBuilder &MIRBuilder) { … }
void IRTranslator::addSuccessorWithProb(MachineBasicBlock *Src,
MachineBasicBlock *Dst,
BranchProbability Prob) { … }
BranchProbability
IRTranslator::getEdgeProbability(const MachineBasicBlock *Src,
const MachineBasicBlock *Dst) const { … }
bool IRTranslator::translateSwitch(const User &U, MachineIRBuilder &MIB) { … }
void IRTranslator::splitWorkItem(SwitchCG::SwitchWorkList &WorkList,
const SwitchCG::SwitchWorkListItem &W,
Value *Cond, MachineBasicBlock *SwitchMBB,
MachineIRBuilder &MIB) { … }
void IRTranslator::emitJumpTable(SwitchCG::JumpTable &JT,
MachineBasicBlock *MBB) { … }
bool IRTranslator::emitJumpTableHeader(SwitchCG::JumpTable &JT,
SwitchCG::JumpTableHeader &JTH,
MachineBasicBlock *HeaderBB) { … }
void IRTranslator::emitSwitchCase(SwitchCG::CaseBlock &CB,
MachineBasicBlock *SwitchBB,
MachineIRBuilder &MIB) { … }
bool IRTranslator::lowerJumpTableWorkItem(SwitchCG::SwitchWorkListItem W,
MachineBasicBlock *SwitchMBB,
MachineBasicBlock *CurMBB,
MachineBasicBlock *DefaultMBB,
MachineIRBuilder &MIB,
MachineFunction::iterator BBI,
BranchProbability UnhandledProbs,
SwitchCG::CaseClusterIt I,
MachineBasicBlock *Fallthrough,
bool FallthroughUnreachable) { … }
bool IRTranslator::lowerSwitchRangeWorkItem(SwitchCG::CaseClusterIt I,
Value *Cond,
MachineBasicBlock *Fallthrough,
bool FallthroughUnreachable,
BranchProbability UnhandledProbs,
MachineBasicBlock *CurMBB,
MachineIRBuilder &MIB,
MachineBasicBlock *SwitchMBB) { … }
void IRTranslator::emitBitTestHeader(SwitchCG::BitTestBlock &B,
MachineBasicBlock *SwitchBB) { … }
void IRTranslator::emitBitTestCase(SwitchCG::BitTestBlock &BB,
MachineBasicBlock *NextMBB,
BranchProbability BranchProbToNext,
Register Reg, SwitchCG::BitTestCase &B,
MachineBasicBlock *SwitchBB) { … }
bool IRTranslator::lowerBitTestWorkItem(
SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
MachineIRBuilder &MIB, MachineFunction::iterator BBI,
BranchProbability DefaultProb, BranchProbability UnhandledProbs,
SwitchCG::CaseClusterIt I, MachineBasicBlock *Fallthrough,
bool FallthroughUnreachable) { … }
bool IRTranslator::lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W,
Value *Cond,
MachineBasicBlock *SwitchMBB,
MachineBasicBlock *DefaultMBB,
MachineIRBuilder &MIB) { … }
bool IRTranslator::translateIndirectBr(const User &U,
MachineIRBuilder &MIRBuilder) { … }
static bool isSwiftError(const Value *V) { … }
bool IRTranslator::translateLoad(const User &U, MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateStore(const User &U, MachineIRBuilder &MIRBuilder) { … }
static uint64_t getOffsetFromIndices(const User &U, const DataLayout &DL) { … }
bool IRTranslator::translateExtractValue(const User &U,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateInsertValue(const User &U,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateSelect(const User &U,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateCopy(const User &U, const Value &V,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateBitCast(const User &U,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateCast(unsigned Opcode, const User &U,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateGetElementPtr(const User &U,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateMemFunc(const CallInst &CI,
MachineIRBuilder &MIRBuilder,
unsigned Opcode) { … }
bool IRTranslator::translateTrap(const CallInst &CI,
MachineIRBuilder &MIRBuilder,
unsigned Opcode) { … }
bool IRTranslator::translateVectorInterleave2Intrinsic(
const CallInst &CI, MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateVectorDeinterleave2Intrinsic(
const CallInst &CI, MachineIRBuilder &MIRBuilder) { … }
void IRTranslator::getStackGuard(Register DstReg,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateOverflowIntrinsic(const CallInst &CI, unsigned Op,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateFixedPointIntrinsic(unsigned Op, const CallInst &CI,
MachineIRBuilder &MIRBuilder) { … }
unsigned IRTranslator::getSimpleIntrinsicOpcode(Intrinsic::ID ID) { … }
bool IRTranslator::translateSimpleIntrinsic(const CallInst &CI,
Intrinsic::ID ID,
MachineIRBuilder &MIRBuilder) { … }
static unsigned getConstrainedOpcode(Intrinsic::ID ID) { … }
bool IRTranslator::translateConstrainedFPIntrinsic(
const ConstrainedFPIntrinsic &FPI, MachineIRBuilder &MIRBuilder) { … }
std::optional<MCRegister> IRTranslator::getArgPhysReg(Argument &Arg) { … }
bool IRTranslator::translateIfEntryValueArgument(bool isDeclare, Value *Val,
const DILocalVariable *Var,
const DIExpression *Expr,
const DebugLoc &DL,
MachineIRBuilder &MIRBuilder) { … }
static unsigned getConvOpcode(Intrinsic::ID ID) { … }
bool IRTranslator::translateConvergenceControlIntrinsic(
const CallInst &CI, Intrinsic::ID ID, MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateInlineAsm(const CallBase &CB,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateCallBase(const CallBase &CB,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateCall(const User &U, MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::findUnwindDestinations(
const BasicBlock *EHPadBB,
BranchProbability Prob,
SmallVectorImpl<std::pair<MachineBasicBlock *, BranchProbability>>
&UnwindDests) { … }
bool IRTranslator::translateInvoke(const User &U,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateCallBr(const User &U,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateLandingPad(const User &U,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateAlloca(const User &U,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateVAArg(const User &U, MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateUnreachable(const User &U, MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateInsertElement(const User &U,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateInsertVector(const User &U,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateExtractElement(const User &U,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateExtractVector(const User &U,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateShuffleVector(const User &U,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translatePHI(const User &U, MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateAtomicCmpXchg(const User &U,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateAtomicRMW(const User &U,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateFence(const User &U,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translateFreeze(const User &U,
MachineIRBuilder &MIRBuilder) { … }
void IRTranslator::finishPendingPhis() { … }
void IRTranslator::translateDbgValueRecord(Value *V, bool HasArgList,
const DILocalVariable *Variable,
const DIExpression *Expression,
const DebugLoc &DL,
MachineIRBuilder &MIRBuilder) { … }
void IRTranslator::translateDbgDeclareRecord(Value *Address, bool HasArgList,
const DILocalVariable *Variable,
const DIExpression *Expression,
const DebugLoc &DL,
MachineIRBuilder &MIRBuilder) { … }
void IRTranslator::translateDbgInfo(const Instruction &Inst,
MachineIRBuilder &MIRBuilder) { … }
bool IRTranslator::translate(const Instruction &Inst) { … }
bool IRTranslator::translate(const Constant &C, Register Reg) { … }
bool IRTranslator::finalizeBasicBlock(const BasicBlock &BB,
MachineBasicBlock &MBB) { … }
bool IRTranslator::emitSPDescriptorParent(StackProtectorDescriptor &SPD,
MachineBasicBlock *ParentBB) { … }
bool IRTranslator::emitSPDescriptorFailure(StackProtectorDescriptor &SPD,
MachineBasicBlock *FailureBB) { … }
void IRTranslator::finalizeFunction() { … }
static bool checkForMustTailInVarArgFn(bool IsVarArg, const BasicBlock &BB) { … }
bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) { … }