You've already forked linux-packaging-mono
Imported Upstream version 5.18.0.167
Former-commit-id: 289509151e0fee68a1b591a20c9f109c3c789d3a
This commit is contained in:
parent
e19d552987
commit
b084638f15
691
external/llvm/lib/Target/ARM/A15SDOptimizer.cpp
vendored
691
external/llvm/lib/Target/ARM/A15SDOptimizer.cpp
vendored
File diff suppressed because it is too large
Load Diff
68
external/llvm/lib/Target/ARM/ARM.h
vendored
68
external/llvm/lib/Target/ARM/ARM.h
vendored
@ -1,68 +0,0 @@
|
||||
//===-- ARM.h - Top-level interface for ARM representation ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains the entry points for global functions defined in the LLVM
|
||||
// ARM back-end.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_TARGET_ARM_ARM_H
|
||||
#define LLVM_LIB_TARGET_ARM_ARM_H
|
||||
|
||||
#include "llvm/Support/CodeGen.h"
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class ARMAsmPrinter;
|
||||
class ARMBaseTargetMachine;
|
||||
class ARMRegisterBankInfo;
|
||||
class ARMSubtarget;
|
||||
struct BasicBlockInfo;
|
||||
class Function;
|
||||
class FunctionPass;
|
||||
class InstructionSelector;
|
||||
class MachineBasicBlock;
|
||||
class MachineFunction;
|
||||
class MachineInstr;
|
||||
class MCInst;
|
||||
class PassRegistry;
|
||||
|
||||
FunctionPass *createARMISelDag(ARMBaseTargetMachine &TM,
|
||||
CodeGenOpt::Level OptLevel);
|
||||
FunctionPass *createA15SDOptimizerPass();
|
||||
FunctionPass *createARMLoadStoreOptimizationPass(bool PreAlloc = false);
|
||||
FunctionPass *createARMExpandPseudoPass();
|
||||
FunctionPass *createARMConstantIslandPass();
|
||||
FunctionPass *createMLxExpansionPass();
|
||||
FunctionPass *createThumb2ITBlockPass();
|
||||
FunctionPass *createARMOptimizeBarriersPass();
|
||||
FunctionPass *createThumb2SizeReductionPass(
|
||||
std::function<bool(const Function &)> Ftor = nullptr);
|
||||
InstructionSelector *
|
||||
createARMInstructionSelector(const ARMBaseTargetMachine &TM, const ARMSubtarget &STI,
|
||||
const ARMRegisterBankInfo &RBI);
|
||||
|
||||
void LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
|
||||
ARMAsmPrinter &AP);
|
||||
|
||||
void computeBlockSize(MachineFunction *MF, MachineBasicBlock *MBB,
|
||||
BasicBlockInfo &BBI);
|
||||
std::vector<BasicBlockInfo> computeAllBlockSizes(MachineFunction *MF);
|
||||
|
||||
void initializeARMLoadStoreOptPass(PassRegistry &);
|
||||
void initializeARMPreAllocLoadStoreOptPass(PassRegistry &);
|
||||
void initializeARMConstantIslandsPass(PassRegistry &);
|
||||
void initializeARMExpandPseudoPass(PassRegistry &);
|
||||
void initializeThumb2SizeReducePass(PassRegistry &);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_ARM_ARM_H
|
1045
external/llvm/lib/Target/ARM/ARM.td
vendored
1045
external/llvm/lib/Target/ARM/ARM.td
vendored
File diff suppressed because it is too large
Load Diff
2050
external/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
vendored
2050
external/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
vendored
File diff suppressed because it is too large
Load Diff
157
external/llvm/lib/Target/ARM/ARMAsmPrinter.h
vendored
157
external/llvm/lib/Target/ARM/ARMAsmPrinter.h
vendored
@ -1,157 +0,0 @@
|
||||
//===-- ARMAsmPrinter.h - ARM implementation of AsmPrinter ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_TARGET_ARM_ARMASMPRINTER_H
|
||||
#define LLVM_LIB_TARGET_ARM_ARMASMPRINTER_H
|
||||
|
||||
#include "ARMSubtarget.h"
|
||||
#include "llvm/CodeGen/AsmPrinter.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class ARMFunctionInfo;
|
||||
class MCOperand;
|
||||
class MachineConstantPool;
|
||||
class MachineOperand;
|
||||
class MCSymbol;
|
||||
|
||||
namespace ARM {
|
||||
enum DW_ISA {
|
||||
DW_ISA_ARM_thumb = 1,
|
||||
DW_ISA_ARM_arm = 2
|
||||
};
|
||||
}
|
||||
|
||||
class LLVM_LIBRARY_VISIBILITY ARMAsmPrinter : public AsmPrinter {
|
||||
|
||||
/// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
|
||||
/// make the right decision when printing asm code for different targets.
|
||||
const ARMSubtarget *Subtarget;
|
||||
|
||||
/// AFI - Keep a pointer to ARMFunctionInfo for the current
|
||||
/// MachineFunction.
|
||||
ARMFunctionInfo *AFI;
|
||||
|
||||
/// MCP - Keep a pointer to constantpool entries of the current
|
||||
/// MachineFunction.
|
||||
const MachineConstantPool *MCP;
|
||||
|
||||
/// InConstantPool - Maintain state when emitting a sequence of constant
|
||||
/// pool entries so we can properly mark them as data regions.
|
||||
bool InConstantPool;
|
||||
|
||||
/// ThumbIndirectPads - These maintain a per-function list of jump pad
|
||||
/// labels used for ARMv4t thumb code to make register indirect calls.
|
||||
SmallVector<std::pair<unsigned, MCSymbol*>, 4> ThumbIndirectPads;
|
||||
|
||||
/// OptimizationGoals - Maintain a combined optimization goal for all
|
||||
/// functions in a module: one of Tag_ABI_optimization_goals values,
|
||||
/// -1 if uninitialized, 0 if conflicting goals
|
||||
int OptimizationGoals;
|
||||
|
||||
/// List of globals that have had their storage promoted to a constant
|
||||
/// pool. This lives between calls to runOnMachineFunction and collects
|
||||
/// data from every MachineFunction. It is used during doFinalization
|
||||
/// when all non-function globals are emitted.
|
||||
SmallPtrSet<const GlobalVariable*,2> PromotedGlobals;
|
||||
/// Set of globals in PromotedGlobals that we've emitted labels for.
|
||||
/// We need to emit labels even for promoted globals so that DWARF
|
||||
/// debug info can link properly.
|
||||
SmallPtrSet<const GlobalVariable*,2> EmittedPromotedGlobalLabels;
|
||||
|
||||
public:
|
||||
explicit ARMAsmPrinter(TargetMachine &TM,
|
||||
std::unique_ptr<MCStreamer> Streamer);
|
||||
|
||||
StringRef getPassName() const override {
|
||||
return "ARM Assembly Printer";
|
||||
}
|
||||
|
||||
void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
|
||||
|
||||
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
|
||||
unsigned AsmVariant, const char *ExtraCode,
|
||||
raw_ostream &O) override;
|
||||
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
|
||||
unsigned AsmVariant, const char *ExtraCode,
|
||||
raw_ostream &O) override;
|
||||
|
||||
void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
|
||||
const MCSubtargetInfo *EndInfo) const override;
|
||||
|
||||
void EmitJumpTableAddrs(const MachineInstr *MI);
|
||||
void EmitJumpTableInsts(const MachineInstr *MI);
|
||||
void EmitJumpTableTBInst(const MachineInstr *MI, unsigned OffsetWidth);
|
||||
void EmitInstruction(const MachineInstr *MI) override;
|
||||
bool runOnMachineFunction(MachineFunction &F) override;
|
||||
|
||||
void EmitConstantPool() override {
|
||||
// we emit constant pools customly!
|
||||
}
|
||||
void EmitFunctionBodyEnd() override;
|
||||
void EmitFunctionEntryLabel() override;
|
||||
void EmitStartOfAsmFile(Module &M) override;
|
||||
void EmitEndOfAsmFile(Module &M) override;
|
||||
void EmitXXStructor(const DataLayout &DL, const Constant *CV) override;
|
||||
void EmitGlobalVariable(const GlobalVariable *GV) override;
|
||||
|
||||
// lowerOperand - Convert a MachineOperand into the equivalent MCOperand.
|
||||
bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp);
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
// XRay implementation
|
||||
//===------------------------------------------------------------------===//
|
||||
public:
|
||||
// XRay-specific lowering for ARM.
|
||||
void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI);
|
||||
void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI);
|
||||
void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI);
|
||||
|
||||
private:
|
||||
void EmitSled(const MachineInstr &MI, SledKind Kind);
|
||||
|
||||
// Helpers for EmitStartOfAsmFile() and EmitEndOfAsmFile()
|
||||
void emitAttributes();
|
||||
|
||||
// Generic helper used to emit e.g. ARMv5 mul pseudos
|
||||
void EmitPatchedInstruction(const MachineInstr *MI, unsigned TargetOpc);
|
||||
|
||||
void EmitUnwindingInstruction(const MachineInstr *MI);
|
||||
|
||||
// emitPseudoExpansionLowering - tblgen'erated.
|
||||
bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
|
||||
const MachineInstr *MI);
|
||||
|
||||
public:
|
||||
unsigned getISAEncoding() override {
|
||||
// ARM/Darwin adds ISA to the DWARF info for each function.
|
||||
const Triple &TT = TM.getTargetTriple();
|
||||
if (!TT.isOSBinFormatMachO())
|
||||
return 0;
|
||||
bool isThumb = TT.isThumb() ||
|
||||
TT.getSubArch() == Triple::ARMSubArch_v7m ||
|
||||
TT.getSubArch() == Triple::ARMSubArch_v6m;
|
||||
return isThumb ? ARM::DW_ISA_ARM_thumb : ARM::DW_ISA_ARM_arm;
|
||||
}
|
||||
|
||||
private:
|
||||
MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol);
|
||||
MCSymbol *GetARMJTIPICJumpTableLabel(unsigned uid) const;
|
||||
|
||||
MCSymbol *GetARMGVSymbol(const GlobalValue *GV, unsigned char TargetFlags);
|
||||
|
||||
public:
|
||||
/// EmitMachineConstantPoolValue - Print a machine constantpool value to
|
||||
/// the .s file.
|
||||
void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override;
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -1 +0,0 @@
|
||||
cff24a10bb5f89192fd318c2d46e8e936d079f08
|
558
external/llvm/lib/Target/ARM/ARMBaseInstrInfo.h
vendored
558
external/llvm/lib/Target/ARM/ARMBaseInstrInfo.h
vendored
File diff suppressed because it is too large
Load Diff
865
external/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
vendored
865
external/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
vendored
File diff suppressed because it is too large
Load Diff
215
external/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h
vendored
215
external/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h
vendored
@ -1,215 +0,0 @@
|
||||
//===-- ARMBaseRegisterInfo.h - ARM Register Information Impl ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains the base ARM implementation of TargetRegisterInfo class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_TARGET_ARM_ARMBASEREGISTERINFO_H
|
||||
#define LLVM_LIB_TARGET_ARM_ARMBASEREGISTERINFO_H
|
||||
|
||||
#include "MCTargetDesc/ARMBaseInfo.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/TargetRegisterInfo.h"
|
||||
#include "llvm/IR/CallingConv.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include <cstdint>
|
||||
|
||||
#define GET_REGINFO_HEADER
|
||||
#include "ARMGenRegisterInfo.inc"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class LiveIntervals;
|
||||
|
||||
/// Register allocation hints.
|
||||
namespace ARMRI {
|
||||
|
||||
enum {
|
||||
RegPairOdd = 1,
|
||||
RegPairEven = 2
|
||||
};
|
||||
|
||||
} // end namespace ARMRI
|
||||
|
||||
/// isARMArea1Register - Returns true if the register is a low register (r0-r7)
|
||||
/// or a stack/pc register that we should push/pop.
|
||||
static inline bool isARMArea1Register(unsigned Reg, bool isIOS) {
|
||||
using namespace ARM;
|
||||
|
||||
switch (Reg) {
|
||||
case R0: case R1: case R2: case R3:
|
||||
case R4: case R5: case R6: case R7:
|
||||
case LR: case SP: case PC:
|
||||
return true;
|
||||
case R8: case R9: case R10: case R11: case R12:
|
||||
// For iOS we want r7 and lr to be next to each other.
|
||||
return !isIOS;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool isARMArea2Register(unsigned Reg, bool isIOS) {
|
||||
using namespace ARM;
|
||||
|
||||
switch (Reg) {
|
||||
case R8: case R9: case R10: case R11: case R12:
|
||||
// iOS has this second area.
|
||||
return isIOS;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool isARMArea3Register(unsigned Reg, bool isIOS) {
|
||||
using namespace ARM;
|
||||
|
||||
switch (Reg) {
|
||||
case D15: case D14: case D13: case D12:
|
||||
case D11: case D10: case D9: case D8:
|
||||
case D7: case D6: case D5: case D4:
|
||||
case D3: case D2: case D1: case D0:
|
||||
case D31: case D30: case D29: case D28:
|
||||
case D27: case D26: case D25: case D24:
|
||||
case D23: case D22: case D21: case D20:
|
||||
case D19: case D18: case D17: case D16:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool isCalleeSavedRegister(unsigned Reg,
|
||||
const MCPhysReg *CSRegs) {
|
||||
for (unsigned i = 0; CSRegs[i]; ++i)
|
||||
if (Reg == CSRegs[i])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
class ARMBaseRegisterInfo : public ARMGenRegisterInfo {
|
||||
protected:
|
||||
/// BasePtr - ARM physical register used as a base ptr in complex stack
|
||||
/// frames. I.e., when we need a 3rd base, not just SP and FP, due to
|
||||
/// variable size stack objects.
|
||||
unsigned BasePtr = ARM::R6;
|
||||
|
||||
// Can be only subclassed.
|
||||
explicit ARMBaseRegisterInfo();
|
||||
|
||||
// Return the opcode that implements 'Op', or 0 if no opcode
|
||||
unsigned getOpcode(int Op) const;
|
||||
|
||||
public:
|
||||
/// Code Generation virtual methods...
|
||||
const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
|
||||
const MCPhysReg *
|
||||
getCalleeSavedRegsViaCopy(const MachineFunction *MF) const;
|
||||
const uint32_t *getCallPreservedMask(const MachineFunction &MF,
|
||||
CallingConv::ID) const override;
|
||||
const uint32_t *getNoPreservedMask() const override;
|
||||
const uint32_t *getTLSCallPreservedMask(const MachineFunction &MF) const;
|
||||
const uint32_t *getSjLjDispatchPreservedMask(const MachineFunction &MF) const;
|
||||
|
||||
/// getThisReturnPreservedMask - Returns a call preserved mask specific to the
|
||||
/// case that 'returned' is on an i32 first argument if the calling convention
|
||||
/// is one that can (partially) model this attribute with a preserved mask
|
||||
/// (i.e. it is a calling convention that uses the same register for the first
|
||||
/// i32 argument and an i32 return value)
|
||||
///
|
||||
/// Should return NULL in the case that the calling convention does not have
|
||||
/// this property
|
||||
const uint32_t *getThisReturnPreservedMask(const MachineFunction &MF,
|
||||
CallingConv::ID) const;
|
||||
|
||||
BitVector getReservedRegs(const MachineFunction &MF) const override;
|
||||
|
||||
const TargetRegisterClass *
|
||||
getPointerRegClass(const MachineFunction &MF,
|
||||
unsigned Kind = 0) const override;
|
||||
const TargetRegisterClass *
|
||||
getCrossCopyRegClass(const TargetRegisterClass *RC) const override;
|
||||
|
||||
const TargetRegisterClass *
|
||||
getLargestLegalSuperClass(const TargetRegisterClass *RC,
|
||||
const MachineFunction &MF) const override;
|
||||
|
||||
unsigned getRegPressureLimit(const TargetRegisterClass *RC,
|
||||
MachineFunction &MF) const override;
|
||||
|
||||
bool getRegAllocationHints(unsigned VirtReg,
|
||||
ArrayRef<MCPhysReg> Order,
|
||||
SmallVectorImpl<MCPhysReg> &Hints,
|
||||
const MachineFunction &MF,
|
||||
const VirtRegMap *VRM,
|
||||
const LiveRegMatrix *Matrix) const override;
|
||||
|
||||
void updateRegAllocHint(unsigned Reg, unsigned NewReg,
|
||||
MachineFunction &MF) const override;
|
||||
|
||||
bool hasBasePointer(const MachineFunction &MF) const;
|
||||
|
||||
bool canRealignStack(const MachineFunction &MF) const override;
|
||||
int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
|
||||
int Idx) const override;
|
||||
bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
|
||||
void materializeFrameBaseRegister(MachineBasicBlock *MBB,
|
||||
unsigned BaseReg, int FrameIdx,
|
||||
int64_t Offset) const override;
|
||||
void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
|
||||
int64_t Offset) const override;
|
||||
bool isFrameOffsetLegal(const MachineInstr *MI, unsigned BaseReg,
|
||||
int64_t Offset) const override;
|
||||
|
||||
bool cannotEliminateFrame(const MachineFunction &MF) const;
|
||||
|
||||
// Debug information queries.
|
||||
unsigned getFrameRegister(const MachineFunction &MF) const override;
|
||||
unsigned getBaseRegister() const { return BasePtr; }
|
||||
|
||||
bool isLowRegister(unsigned Reg) const;
|
||||
|
||||
|
||||
/// emitLoadConstPool - Emits a load from constpool to materialize the
|
||||
/// specified immediate.
|
||||
virtual void
|
||||
emitLoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
|
||||
const DebugLoc &dl, unsigned DestReg, unsigned SubIdx,
|
||||
int Val, ARMCC::CondCodes Pred = ARMCC::AL,
|
||||
unsigned PredReg = 0,
|
||||
unsigned MIFlags = MachineInstr::NoFlags) const;
|
||||
|
||||
/// Code Generation virtual methods...
|
||||
bool requiresRegisterScavenging(const MachineFunction &MF) const override;
|
||||
|
||||
bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const override;
|
||||
|
||||
bool requiresFrameIndexScavenging(const MachineFunction &MF) const override;
|
||||
|
||||
bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override;
|
||||
|
||||
void eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||
int SPAdj, unsigned FIOperandNum,
|
||||
RegScavenger *RS = nullptr) const override;
|
||||
|
||||
/// \brief SrcRC and DstRC will be morphed into NewRC if this returns true
|
||||
bool shouldCoalesce(MachineInstr *MI,
|
||||
const TargetRegisterClass *SrcRC,
|
||||
unsigned SubReg,
|
||||
const TargetRegisterClass *DstRC,
|
||||
unsigned DstSubReg,
|
||||
const TargetRegisterClass *NewRC,
|
||||
LiveIntervals &LIS) const override;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_ARM_ARMBASEREGISTERINFO_H
|
109
external/llvm/lib/Target/ARM/ARMBasicBlockInfo.h
vendored
109
external/llvm/lib/Target/ARM/ARMBasicBlockInfo.h
vendored
@ -1,109 +0,0 @@
|
||||
//===-- ARMBasicBlockInfo.h - Basic Block Information -----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Utility functions and data structure for computing block size.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_TARGET_ARM_ARMBASICBLOCKINFO_H
|
||||
#define LLVM_LIB_TARGET_ARM_ARMBASICBLOCKINFO_H
|
||||
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// UnknownPadding - Return the worst case padding that could result from
|
||||
/// unknown offset bits. This does not include alignment padding caused by
|
||||
/// known offset bits.
|
||||
///
|
||||
/// @param LogAlign log2(alignment)
|
||||
/// @param KnownBits Number of known low offset bits.
|
||||
inline unsigned UnknownPadding(unsigned LogAlign, unsigned KnownBits) {
|
||||
if (KnownBits < LogAlign)
|
||||
return (1u << LogAlign) - (1u << KnownBits);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// BasicBlockInfo - Information about the offset and size of a single
|
||||
/// basic block.
|
||||
struct BasicBlockInfo {
|
||||
/// Offset - Distance from the beginning of the function to the beginning
|
||||
/// of this basic block.
|
||||
///
|
||||
/// Offsets are computed assuming worst case padding before an aligned
|
||||
/// block. This means that subtracting basic block offsets always gives a
|
||||
/// conservative estimate of the real distance which may be smaller.
|
||||
///
|
||||
/// Because worst case padding is used, the computed offset of an aligned
|
||||
/// block may not actually be aligned.
|
||||
unsigned Offset = 0;
|
||||
|
||||
/// Size - Size of the basic block in bytes. If the block contains
|
||||
/// inline assembly, this is a worst case estimate.
|
||||
///
|
||||
/// The size does not include any alignment padding whether from the
|
||||
/// beginning of the block, or from an aligned jump table at the end.
|
||||
unsigned Size = 0;
|
||||
|
||||
/// KnownBits - The number of low bits in Offset that are known to be
|
||||
/// exact. The remaining bits of Offset are an upper bound.
|
||||
uint8_t KnownBits = 0;
|
||||
|
||||
/// Unalign - When non-zero, the block contains instructions (inline asm)
|
||||
/// of unknown size. The real size may be smaller than Size bytes by a
|
||||
/// multiple of 1 << Unalign.
|
||||
uint8_t Unalign = 0;
|
||||
|
||||
/// PostAlign - When non-zero, the block terminator contains a .align
|
||||
/// directive, so the end of the block is aligned to 1 << PostAlign
|
||||
/// bytes.
|
||||
uint8_t PostAlign = 0;
|
||||
|
||||
BasicBlockInfo() = default;
|
||||
|
||||
/// Compute the number of known offset bits internally to this block.
|
||||
/// This number should be used to predict worst case padding when
|
||||
/// splitting the block.
|
||||
unsigned internalKnownBits() const {
|
||||
unsigned Bits = Unalign ? Unalign : KnownBits;
|
||||
// If the block size isn't a multiple of the known bits, assume the
|
||||
// worst case padding.
|
||||
if (Size & ((1u << Bits) - 1))
|
||||
Bits = countTrailingZeros(Size);
|
||||
return Bits;
|
||||
}
|
||||
|
||||
/// Compute the offset immediately following this block. If LogAlign is
|
||||
/// specified, return the offset the successor block will get if it has
|
||||
/// this alignment.
|
||||
unsigned postOffset(unsigned LogAlign = 0) const {
|
||||
unsigned PO = Offset + Size;
|
||||
unsigned LA = std::max(unsigned(PostAlign), LogAlign);
|
||||
if (!LA)
|
||||
return PO;
|
||||
// Add alignment padding from the terminator.
|
||||
return PO + UnknownPadding(LA, internalKnownBits());
|
||||
}
|
||||
|
||||
/// Compute the number of known low bits of postOffset. If this block
|
||||
/// contains inline asm, the number of known bits drops to the
|
||||
/// instruction alignment. An aligned terminator may increase the number
|
||||
/// of know bits.
|
||||
/// If LogAlign is given, also consider the alignment of the next block.
|
||||
unsigned postKnownBits(unsigned LogAlign = 0) const {
|
||||
return std::max(std::max(unsigned(PostAlign), LogAlign),
|
||||
internalKnownBits());
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_ARM_ARMBASICBLOCKINFO_H
|
588
external/llvm/lib/Target/ARM/ARMCallLowering.cpp
vendored
588
external/llvm/lib/Target/ARM/ARMCallLowering.cpp
vendored
File diff suppressed because it is too large
Load Diff
62
external/llvm/lib/Target/ARM/ARMCallLowering.h
vendored
62
external/llvm/lib/Target/ARM/ARMCallLowering.h
vendored
@ -1,62 +0,0 @@
|
||||
//===- llvm/lib/Target/ARM/ARMCallLowering.h - Call lowering ----*- C++ -*-===//
|
||||
//
|
||||
// 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_ARM_ARMCALLLOWERING_H
|
||||
#define LLVM_LIB_TARGET_ARM_ARMCALLLOWERING_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
|
||||
#include "llvm/IR/CallingConv.h"
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class ARMTargetLowering;
|
||||
class MachineFunction;
|
||||
class MachineInstrBuilder;
|
||||
class MachineIRBuilder;
|
||||
class Value;
|
||||
|
||||
class ARMCallLowering : public CallLowering {
|
||||
public:
|
||||
ARMCallLowering(const ARMTargetLowering &TLI);
|
||||
|
||||
bool lowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val,
|
||||
unsigned VReg) const override;
|
||||
|
||||
bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F,
|
||||
ArrayRef<unsigned> VRegs) const override;
|
||||
|
||||
bool lowerCall(MachineIRBuilder &MIRBuilder, CallingConv::ID CallConv,
|
||||
const MachineOperand &Callee, const ArgInfo &OrigRet,
|
||||
ArrayRef<ArgInfo> OrigArgs) const override;
|
||||
|
||||
private:
|
||||
bool lowerReturnVal(MachineIRBuilder &MIRBuilder, const Value *Val,
|
||||
unsigned VReg, MachineInstrBuilder &Ret) const;
|
||||
|
||||
using SplitArgTy = std::function<void(unsigned Reg, uint64_t Offset)>;
|
||||
|
||||
/// Split an argument into one or more arguments that the CC lowering can cope
|
||||
/// with (e.g. replace pointers with integers).
|
||||
void splitToValueTypes(const ArgInfo &OrigArg,
|
||||
SmallVectorImpl<ArgInfo> &SplitArgs,
|
||||
MachineFunction &MF,
|
||||
const SplitArgTy &PerformArgSplit) const;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_ARM_ARMCALLLOWERING_H
|
288
external/llvm/lib/Target/ARM/ARMCallingConv.h
vendored
288
external/llvm/lib/Target/ARM/ARMCallingConv.h
vendored
@ -1,288 +0,0 @@
|
||||
//=== ARMCallingConv.h - ARM Custom Calling Convention Routines -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains the custom routines for the ARM Calling Convention that
|
||||
// aren't done by tablegen.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_TARGET_ARM_ARMCALLINGCONV_H
|
||||
#define LLVM_LIB_TARGET_ARM_ARMCALLINGCONV_H
|
||||
|
||||
#include "ARM.h"
|
||||
#include "ARMBaseInstrInfo.h"
|
||||
#include "ARMSubtarget.h"
|
||||
#include "llvm/CodeGen/CallingConvLower.h"
|
||||
#include "llvm/CodeGen/TargetInstrInfo.h"
|
||||
#include "llvm/IR/CallingConv.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
// APCS f64 is in register pairs, possibly split to stack
|
||||
static bool f64AssignAPCS(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
CCState &State, bool CanFail) {
|
||||
static const MCPhysReg RegList[] = { ARM::R0, ARM::R1, ARM::R2, ARM::R3 };
|
||||
|
||||
// Try to get the first register.
|
||||
if (unsigned Reg = State.AllocateReg(RegList))
|
||||
State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
|
||||
else {
|
||||
// For the 2nd half of a v2f64, do not fail.
|
||||
if (CanFail)
|
||||
return false;
|
||||
|
||||
// Put the whole thing on the stack.
|
||||
State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
|
||||
State.AllocateStack(8, 4),
|
||||
LocVT, LocInfo));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Try to get the second register.
|
||||
if (unsigned Reg = State.AllocateReg(RegList))
|
||||
State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
|
||||
else
|
||||
State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
|
||||
State.AllocateStack(4, 4),
|
||||
LocVT, LocInfo));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CC_ARM_APCS_Custom_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State) {
|
||||
if (!f64AssignAPCS(ValNo, ValVT, LocVT, LocInfo, State, true))
|
||||
return false;
|
||||
if (LocVT == MVT::v2f64 &&
|
||||
!f64AssignAPCS(ValNo, ValVT, LocVT, LocInfo, State, false))
|
||||
return false;
|
||||
return true; // we handled it
|
||||
}
|
||||
|
||||
// AAPCS f64 is in aligned register pairs
|
||||
static bool f64AssignAAPCS(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
CCState &State, bool CanFail) {
|
||||
static const MCPhysReg HiRegList[] = { ARM::R0, ARM::R2 };
|
||||
static const MCPhysReg LoRegList[] = { ARM::R1, ARM::R3 };
|
||||
static const MCPhysReg ShadowRegList[] = { ARM::R0, ARM::R1 };
|
||||
static const MCPhysReg GPRArgRegs[] = { ARM::R0, ARM::R1, ARM::R2, ARM::R3 };
|
||||
|
||||
unsigned Reg = State.AllocateReg(HiRegList, ShadowRegList);
|
||||
if (Reg == 0) {
|
||||
|
||||
// If we had R3 unallocated only, now we still must to waste it.
|
||||
Reg = State.AllocateReg(GPRArgRegs);
|
||||
assert((!Reg || Reg == ARM::R3) && "Wrong GPRs usage for f64");
|
||||
|
||||
// For the 2nd half of a v2f64, do not just fail.
|
||||
if (CanFail)
|
||||
return false;
|
||||
|
||||
// Put the whole thing on the stack.
|
||||
State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
|
||||
State.AllocateStack(8, 8),
|
||||
LocVT, LocInfo));
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned i;
|
||||
for (i = 0; i < 2; ++i)
|
||||
if (HiRegList[i] == Reg)
|
||||
break;
|
||||
|
||||
unsigned T = State.AllocateReg(LoRegList[i]);
|
||||
(void)T;
|
||||
assert(T == LoRegList[i] && "Could not allocate register");
|
||||
|
||||
State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
|
||||
State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i],
|
||||
LocVT, LocInfo));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CC_ARM_AAPCS_Custom_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State) {
|
||||
if (!f64AssignAAPCS(ValNo, ValVT, LocVT, LocInfo, State, true))
|
||||
return false;
|
||||
if (LocVT == MVT::v2f64 &&
|
||||
!f64AssignAAPCS(ValNo, ValVT, LocVT, LocInfo, State, false))
|
||||
return false;
|
||||
return true; // we handled it
|
||||
}
|
||||
|
||||
static bool f64RetAssign(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo, CCState &State) {
|
||||
static const MCPhysReg HiRegList[] = { ARM::R0, ARM::R2 };
|
||||
static const MCPhysReg LoRegList[] = { ARM::R1, ARM::R3 };
|
||||
|
||||
unsigned Reg = State.AllocateReg(HiRegList, LoRegList);
|
||||
if (Reg == 0)
|
||||
return false; // we didn't handle it
|
||||
|
||||
unsigned i;
|
||||
for (i = 0; i < 2; ++i)
|
||||
if (HiRegList[i] == Reg)
|
||||
break;
|
||||
|
||||
State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
|
||||
State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i],
|
||||
LocVT, LocInfo));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool RetCC_ARM_APCS_Custom_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State) {
|
||||
if (!f64RetAssign(ValNo, ValVT, LocVT, LocInfo, State))
|
||||
return false;
|
||||
if (LocVT == MVT::v2f64 && !f64RetAssign(ValNo, ValVT, LocVT, LocInfo, State))
|
||||
return false;
|
||||
return true; // we handled it
|
||||
}
|
||||
|
||||
static bool RetCC_ARM_AAPCS_Custom_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State) {
|
||||
return RetCC_ARM_APCS_Custom_f64(ValNo, ValVT, LocVT, LocInfo, ArgFlags,
|
||||
State);
|
||||
}
|
||||
|
||||
static const MCPhysReg RRegList[] = { ARM::R0, ARM::R1, ARM::R2, ARM::R3 };
|
||||
|
||||
static const MCPhysReg SRegList[] = { ARM::S0, ARM::S1, ARM::S2, ARM::S3,
|
||||
ARM::S4, ARM::S5, ARM::S6, ARM::S7,
|
||||
ARM::S8, ARM::S9, ARM::S10, ARM::S11,
|
||||
ARM::S12, ARM::S13, ARM::S14, ARM::S15 };
|
||||
static const MCPhysReg DRegList[] = { ARM::D0, ARM::D1, ARM::D2, ARM::D3,
|
||||
ARM::D4, ARM::D5, ARM::D6, ARM::D7 };
|
||||
static const MCPhysReg QRegList[] = { ARM::Q0, ARM::Q1, ARM::Q2, ARM::Q3 };
|
||||
|
||||
|
||||
// Allocate part of an AAPCS HFA or HVA. We assume that each member of the HA
|
||||
// has InConsecutiveRegs set, and that the last member also has
|
||||
// InConsecutiveRegsLast set. We must process all members of the HA before
|
||||
// we can allocate it, as we need to know the total number of registers that
|
||||
// will be needed in order to (attempt to) allocate a contiguous block.
|
||||
static bool CC_ARM_AAPCS_Custom_Aggregate(unsigned &ValNo, MVT &ValVT,
|
||||
MVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State) {
|
||||
SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs();
|
||||
|
||||
// AAPCS HFAs must have 1-4 elements, all of the same type
|
||||
if (PendingMembers.size() > 0)
|
||||
assert(PendingMembers[0].getLocVT() == LocVT);
|
||||
|
||||
// Add the argument to the list to be allocated once we know the size of the
|
||||
// aggregate. Store the type's required alignmnent as extra info for later: in
|
||||
// the [N x i64] case all trace has been removed by the time we actually get
|
||||
// to do allocation.
|
||||
PendingMembers.push_back(CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo,
|
||||
ArgFlags.getOrigAlign()));
|
||||
|
||||
if (!ArgFlags.isInConsecutiveRegsLast())
|
||||
return true;
|
||||
|
||||
// Try to allocate a contiguous block of registers, each of the correct
|
||||
// size to hold one member.
|
||||
auto &DL = State.getMachineFunction().getDataLayout();
|
||||
unsigned StackAlign = DL.getStackAlignment();
|
||||
unsigned Align = std::min(PendingMembers[0].getExtraInfo(), StackAlign);
|
||||
|
||||
ArrayRef<MCPhysReg> RegList;
|
||||
switch (LocVT.SimpleTy) {
|
||||
case MVT::i32: {
|
||||
RegList = RRegList;
|
||||
unsigned RegIdx = State.getFirstUnallocated(RegList);
|
||||
|
||||
// First consume all registers that would give an unaligned object. Whether
|
||||
// we go on stack or in regs, no-one will be using them in future.
|
||||
unsigned RegAlign = alignTo(Align, 4) / 4;
|
||||
while (RegIdx % RegAlign != 0 && RegIdx < RegList.size())
|
||||
State.AllocateReg(RegList[RegIdx++]);
|
||||
|
||||
break;
|
||||
}
|
||||
case MVT::f32:
|
||||
RegList = SRegList;
|
||||
break;
|
||||
case MVT::f64:
|
||||
RegList = DRegList;
|
||||
break;
|
||||
case MVT::v2f64:
|
||||
RegList = QRegList;
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unexpected member type for block aggregate");
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned RegResult = State.AllocateRegBlock(RegList, PendingMembers.size());
|
||||
if (RegResult) {
|
||||
for (SmallVectorImpl<CCValAssign>::iterator It = PendingMembers.begin();
|
||||
It != PendingMembers.end(); ++It) {
|
||||
It->convertToReg(RegResult);
|
||||
State.addLoc(*It);
|
||||
++RegResult;
|
||||
}
|
||||
PendingMembers.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Register allocation failed, we'll be needing the stack
|
||||
unsigned Size = LocVT.getSizeInBits() / 8;
|
||||
if (LocVT == MVT::i32 && State.getNextStackOffset() == 0) {
|
||||
// If nothing else has used the stack until this point, a non-HFA aggregate
|
||||
// can be split between regs and stack.
|
||||
unsigned RegIdx = State.getFirstUnallocated(RegList);
|
||||
for (auto &It : PendingMembers) {
|
||||
if (RegIdx >= RegList.size())
|
||||
It.convertToMem(State.AllocateStack(Size, Size));
|
||||
else
|
||||
It.convertToReg(State.AllocateReg(RegList[RegIdx++]));
|
||||
|
||||
State.addLoc(It);
|
||||
}
|
||||
PendingMembers.clear();
|
||||
return true;
|
||||
} else if (LocVT != MVT::i32)
|
||||
RegList = SRegList;
|
||||
|
||||
// Mark all regs as unavailable (AAPCS rule C.2.vfp for VFP, C.6 for core)
|
||||
for (auto Reg : RegList)
|
||||
State.AllocateReg(Reg);
|
||||
|
||||
for (auto &It : PendingMembers) {
|
||||
It.convertToMem(State.AllocateStack(Size, Align));
|
||||
State.addLoc(It);
|
||||
|
||||
// After the first item has been allocated, the rest are packed as tightly
|
||||
// as possible. (E.g. an incoming i64 would have starting Align of 8, but
|
||||
// we'll be allocating a bunch of i32 slots).
|
||||
Align = Size;
|
||||
}
|
||||
|
||||
// All pending members have now been allocated
|
||||
PendingMembers.clear();
|
||||
|
||||
// This will be allocated by the last member of the aggregate
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
336
external/llvm/lib/Target/ARM/ARMCallingConv.td
vendored
336
external/llvm/lib/Target/ARM/ARMCallingConv.td
vendored
@ -1,336 +0,0 @@
|
||||
//===-- ARMCallingConv.td - Calling Conventions for ARM ----*- tablegen -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
// This describes the calling conventions for ARM architecture.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// CCIfAlign - Match of the original alignment of the arg
|
||||
class CCIfAlign<string Align, CCAction A>:
|
||||
CCIf<!strconcat("ArgFlags.getOrigAlign() == ", Align), A>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ARM APCS Calling Convention
|
||||
//===----------------------------------------------------------------------===//
|
||||
def CC_ARM_APCS : CallingConv<[
|
||||
|
||||
// Handles byval parameters.
|
||||
CCIfByVal<CCPassByVal<4, 4>>,
|
||||
|
||||
CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
|
||||
|
||||
// Pass SwiftSelf in a callee saved register.
|
||||
CCIfSwiftSelf<CCIfType<[i32], CCAssignToReg<[R10]>>>,
|
||||
|
||||
// A SwiftError is passed in R8.
|
||||
CCIfSwiftError<CCIfType<[i32], CCAssignToReg<[R8]>>>,
|
||||
|
||||
// Handle all vector types as either f64 or v2f64.
|
||||
CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
||||
CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
||||
|
||||
// f64 and v2f64 are passed in adjacent GPRs, possibly split onto the stack
|
||||
CCIfType<[f64, v2f64], CCCustom<"CC_ARM_APCS_Custom_f64">>,
|
||||
|
||||
CCIfType<[f32], CCBitConvertToType<i32>>,
|
||||
CCIfType<[i32], CCAssignToReg<[R0, R1, R2, R3]>>,
|
||||
|
||||
CCIfType<[i32], CCAssignToStack<4, 4>>,
|
||||
CCIfType<[f64], CCAssignToStack<8, 4>>,
|
||||
CCIfType<[v2f64], CCAssignToStack<16, 4>>
|
||||
]>;
|
||||
|
||||
def RetCC_ARM_APCS : CallingConv<[
|
||||
CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
|
||||
CCIfType<[f32], CCBitConvertToType<i32>>,
|
||||
|
||||
// Pass SwiftSelf in a callee saved register.
|
||||
CCIfSwiftSelf<CCIfType<[i32], CCAssignToReg<[R10]>>>,
|
||||
|
||||
// A SwiftError is returned in R8.
|
||||
CCIfSwiftError<CCIfType<[i32], CCAssignToReg<[R8]>>>,
|
||||
|
||||
// Handle all vector types as either f64 or v2f64.
|
||||
CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
||||
CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
||||
|
||||
CCIfType<[f64, v2f64], CCCustom<"RetCC_ARM_APCS_Custom_f64">>,
|
||||
|
||||
CCIfType<[i32], CCAssignToReg<[R0, R1, R2, R3]>>,
|
||||
CCIfType<[i64], CCAssignToRegWithShadow<[R0, R2], [R1, R3]>>
|
||||
]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ARM APCS Calling Convention for FastCC (when VFP2 or later is available)
|
||||
//===----------------------------------------------------------------------===//
|
||||
def FastCC_ARM_APCS : CallingConv<[
|
||||
// Handle all vector types as either f64 or v2f64.
|
||||
CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
||||
CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
||||
|
||||
CCIfType<[v2f64], CCAssignToReg<[Q0, Q1, Q2, Q3]>>,
|
||||
CCIfType<[f64], CCAssignToReg<[D0, D1, D2, D3, D4, D5, D6, D7]>>,
|
||||
CCIfType<[f32], CCAssignToReg<[S0, S1, S2, S3, S4, S5, S6, S7, S8,
|
||||
S9, S10, S11, S12, S13, S14, S15]>>,
|
||||
|
||||
// CPRCs may be allocated to co-processor registers or the stack - they
|
||||
// may never be allocated to core registers.
|
||||
CCIfType<[f32], CCAssignToStackWithShadow<4, 4, [Q0, Q1, Q2, Q3]>>,
|
||||
CCIfType<[f64], CCAssignToStackWithShadow<8, 4, [Q0, Q1, Q2, Q3]>>,
|
||||
CCIfType<[v2f64], CCAssignToStackWithShadow<16, 4, [Q0, Q1, Q2, Q3]>>,
|
||||
|
||||
CCDelegateTo<CC_ARM_APCS>
|
||||
]>;
|
||||
|
||||
def RetFastCC_ARM_APCS : CallingConv<[
|
||||
// Handle all vector types as either f64 or v2f64.
|
||||
CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
||||
CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
||||
|
||||
CCIfType<[v2f64], CCAssignToReg<[Q0, Q1, Q2, Q3]>>,
|
||||
CCIfType<[f64], CCAssignToReg<[D0, D1, D2, D3, D4, D5, D6, D7]>>,
|
||||
CCIfType<[f32], CCAssignToReg<[S0, S1, S2, S3, S4, S5, S6, S7, S8,
|
||||
S9, S10, S11, S12, S13, S14, S15]>>,
|
||||
CCDelegateTo<RetCC_ARM_APCS>
|
||||
]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ARM APCS Calling Convention for GHC
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CC_ARM_APCS_GHC : CallingConv<[
|
||||
// Handle all vector types as either f64 or v2f64.
|
||||
CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
||||
CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
||||
|
||||
CCIfType<[v2f64], CCAssignToReg<[Q4, Q5]>>,
|
||||
CCIfType<[f64], CCAssignToReg<[D8, D9, D10, D11]>>,
|
||||
CCIfType<[f32], CCAssignToReg<[S16, S17, S18, S19, S20, S21, S22, S23]>>,
|
||||
|
||||
// Promote i8/i16 arguments to i32.
|
||||
CCIfType<[i8, i16], CCPromoteToType<i32>>,
|
||||
|
||||
// Pass in STG registers: Base, Sp, Hp, R1, R2, R3, R4, SpLim
|
||||
CCIfType<[i32], CCAssignToReg<[R4, R5, R6, R7, R8, R9, R10, R11]>>
|
||||
]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ARM AAPCS (EABI) Calling Convention, common parts
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CC_ARM_AAPCS_Common : CallingConv<[
|
||||
|
||||
CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
|
||||
|
||||
// i64/f64 is passed in even pairs of GPRs
|
||||
// i64 is 8-aligned i32 here, so we may need to eat R1 as a pad register
|
||||
// (and the same is true for f64 if VFP is not enabled)
|
||||
CCIfType<[i32], CCIfAlign<"8", CCAssignToRegWithShadow<[R0, R2], [R0, R1]>>>,
|
||||
CCIfType<[i32], CCIf<"ArgFlags.getOrigAlign() != 8",
|
||||
CCAssignToReg<[R0, R1, R2, R3]>>>,
|
||||
|
||||
CCIfType<[i32], CCIfAlign<"8", CCAssignToStackWithShadow<4, 8, [R0, R1, R2, R3]>>>,
|
||||
CCIfType<[i32], CCAssignToStackWithShadow<4, 4, [R0, R1, R2, R3]>>,
|
||||
CCIfType<[f32], CCAssignToStackWithShadow<4, 4, [Q0, Q1, Q2, Q3]>>,
|
||||
CCIfType<[f64], CCAssignToStackWithShadow<8, 8, [Q0, Q1, Q2, Q3]>>,
|
||||
CCIfType<[v2f64], CCIfAlign<"16",
|
||||
CCAssignToStackWithShadow<16, 16, [Q0, Q1, Q2, Q3]>>>,
|
||||
CCIfType<[v2f64], CCAssignToStackWithShadow<16, 8, [Q0, Q1, Q2, Q3]>>
|
||||
]>;
|
||||
|
||||
def RetCC_ARM_AAPCS_Common : CallingConv<[
|
||||
CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
|
||||
CCIfType<[i32], CCAssignToReg<[R0, R1, R2, R3]>>,
|
||||
CCIfType<[i64], CCAssignToRegWithShadow<[R0, R2], [R1, R3]>>
|
||||
]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ARM AAPCS (EABI) Calling Convention
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CC_ARM_AAPCS : CallingConv<[
|
||||
// Handles byval parameters.
|
||||
CCIfByVal<CCPassByVal<4, 4>>,
|
||||
|
||||
// The 'nest' parameter, if any, is passed in R12.
|
||||
CCIfNest<CCAssignToReg<[R12]>>,
|
||||
|
||||
// Handle all vector types as either f64 or v2f64.
|
||||
CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
||||
CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
||||
|
||||
// Pass SwiftSelf in a callee saved register.
|
||||
CCIfSwiftSelf<CCIfType<[i32], CCAssignToReg<[R10]>>>,
|
||||
|
||||
// A SwiftError is passed in R8.
|
||||
CCIfSwiftError<CCIfType<[i32], CCAssignToReg<[R8]>>>,
|
||||
|
||||
CCIfType<[f64, v2f64], CCCustom<"CC_ARM_AAPCS_Custom_f64">>,
|
||||
CCIfType<[f32], CCBitConvertToType<i32>>,
|
||||
CCDelegateTo<CC_ARM_AAPCS_Common>
|
||||
]>;
|
||||
|
||||
def RetCC_ARM_AAPCS : CallingConv<[
|
||||
// Handle all vector types as either f64 or v2f64.
|
||||
CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
||||
CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
||||
|
||||
// Pass SwiftSelf in a callee saved register.
|
||||
CCIfSwiftSelf<CCIfType<[i32], CCAssignToReg<[R10]>>>,
|
||||
|
||||
// A SwiftError is returned in R8.
|
||||
CCIfSwiftError<CCIfType<[i32], CCAssignToReg<[R8]>>>,
|
||||
|
||||
CCIfType<[f64, v2f64], CCCustom<"RetCC_ARM_AAPCS_Custom_f64">>,
|
||||
CCIfType<[f32], CCBitConvertToType<i32>>,
|
||||
CCDelegateTo<RetCC_ARM_AAPCS_Common>
|
||||
]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ARM AAPCS-VFP (EABI) Calling Convention
|
||||
// Also used for FastCC (when VFP2 or later is available)
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CC_ARM_AAPCS_VFP : CallingConv<[
|
||||
// Handles byval parameters.
|
||||
CCIfByVal<CCPassByVal<4, 4>>,
|
||||
|
||||
// Handle all vector types as either f64 or v2f64.
|
||||
CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
||||
CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
||||
|
||||
// Pass SwiftSelf in a callee saved register.
|
||||
CCIfSwiftSelf<CCIfType<[i32], CCAssignToReg<[R10]>>>,
|
||||
|
||||
// A SwiftError is passed in R8.
|
||||
CCIfSwiftError<CCIfType<[i32], CCAssignToReg<[R8]>>>,
|
||||
|
||||
// HFAs are passed in a contiguous block of registers, or on the stack
|
||||
CCIfConsecutiveRegs<CCCustom<"CC_ARM_AAPCS_Custom_Aggregate">>,
|
||||
|
||||
CCIfType<[v2f64], CCAssignToReg<[Q0, Q1, Q2, Q3]>>,
|
||||
CCIfType<[f64], CCAssignToReg<[D0, D1, D2, D3, D4, D5, D6, D7]>>,
|
||||
CCIfType<[f32], CCAssignToReg<[S0, S1, S2, S3, S4, S5, S6, S7, S8,
|
||||
S9, S10, S11, S12, S13, S14, S15]>>,
|
||||
CCDelegateTo<CC_ARM_AAPCS_Common>
|
||||
]>;
|
||||
|
||||
def RetCC_ARM_AAPCS_VFP : CallingConv<[
|
||||
// Handle all vector types as either f64 or v2f64.
|
||||
CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
||||
CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
||||
|
||||
// Pass SwiftSelf in a callee saved register.
|
||||
CCIfSwiftSelf<CCIfType<[i32], CCAssignToReg<[R10]>>>,
|
||||
|
||||
// A SwiftError is returned in R8.
|
||||
CCIfSwiftError<CCIfType<[i32], CCAssignToReg<[R8]>>>,
|
||||
|
||||
CCIfType<[v2f64], CCAssignToReg<[Q0, Q1, Q2, Q3]>>,
|
||||
CCIfType<[f64], CCAssignToReg<[D0, D1, D2, D3, D4, D5, D6, D7]>>,
|
||||
CCIfType<[f32], CCAssignToReg<[S0, S1, S2, S3, S4, S5, S6, S7, S8,
|
||||
S9, S10, S11, S12, S13, S14, S15]>>,
|
||||
CCDelegateTo<RetCC_ARM_AAPCS_Common>
|
||||
]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Callee-saved register lists.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CSR_NoRegs : CalleeSavedRegs<(add)>;
|
||||
def CSR_FPRegs : CalleeSavedRegs<(add (sequence "D%u", 0, 31))>;
|
||||
|
||||
def CSR_AAPCS : CalleeSavedRegs<(add LR, R11, R10, R9, R8, R7, R6, R5, R4,
|
||||
(sequence "D%u", 15, 8))>;
|
||||
|
||||
// R8 is used to pass swifterror, remove it from CSR.
|
||||
def CSR_AAPCS_SwiftError : CalleeSavedRegs<(sub CSR_AAPCS, R8)>;
|
||||
|
||||
// The order of callee-saved registers needs to match the order we actually push
|
||||
// them in FrameLowering, because this order is what's used by
|
||||
// PrologEpilogInserter to allocate frame index slots. So when R7 is the frame
|
||||
// pointer, we use this AAPCS alternative.
|
||||
def CSR_AAPCS_SplitPush : CalleeSavedRegs<(add LR, R7, R6, R5, R4,
|
||||
R11, R10, R9, R8,
|
||||
(sequence "D%u", 15, 8))>;
|
||||
|
||||
// R8 is used to pass swifterror, remove it from CSR.
|
||||
def CSR_AAPCS_SplitPush_SwiftError : CalleeSavedRegs<(sub CSR_AAPCS_SplitPush,
|
||||
R8)>;
|
||||
|
||||
// Constructors and destructors return 'this' in the ARM C++ ABI; since 'this'
|
||||
// and the pointer return value are both passed in R0 in these cases, this can
|
||||
// be partially modelled by treating R0 as a callee-saved register
|
||||
// Only the resulting RegMask is used; the SaveList is ignored
|
||||
def CSR_AAPCS_ThisReturn : CalleeSavedRegs<(add LR, R11, R10, R9, R8, R7, R6,
|
||||
R5, R4, (sequence "D%u", 15, 8),
|
||||
R0)>;
|
||||
|
||||
// iOS ABI deviates from ARM standard ABI. R9 is not a callee-saved register.
|
||||
// Also save R7-R4 first to match the stack frame fixed spill areas.
|
||||
def CSR_iOS : CalleeSavedRegs<(add LR, R7, R6, R5, R4, (sub CSR_AAPCS, R9))>;
|
||||
|
||||
// R8 is used to pass swifterror, remove it from CSR.
|
||||
def CSR_iOS_SwiftError : CalleeSavedRegs<(sub CSR_iOS, R8)>;
|
||||
|
||||
def CSR_iOS_ThisReturn : CalleeSavedRegs<(add LR, R7, R6, R5, R4,
|
||||
(sub CSR_AAPCS_ThisReturn, R9))>;
|
||||
|
||||
def CSR_iOS_TLSCall
|
||||
: CalleeSavedRegs<(add LR, SP, (sub(sequence "R%u", 12, 1), R9, R12),
|
||||
(sequence "D%u", 31, 0))>;
|
||||
|
||||
// C++ TLS access function saves all registers except SP. Try to match
|
||||
// the order of CSRs in CSR_iOS.
|
||||
def CSR_iOS_CXX_TLS : CalleeSavedRegs<(add CSR_iOS, (sequence "R%u", 12, 1),
|
||||
(sequence "D%u", 31, 0))>;
|
||||
|
||||
// CSRs that are handled by prologue, epilogue.
|
||||
def CSR_iOS_CXX_TLS_PE : CalleeSavedRegs<(add LR, R12, R11, R7, R5, R4)>;
|
||||
|
||||
// CSRs that are handled explicitly via copies.
|
||||
def CSR_iOS_CXX_TLS_ViaCopy : CalleeSavedRegs<(sub CSR_iOS_CXX_TLS,
|
||||
CSR_iOS_CXX_TLS_PE)>;
|
||||
|
||||
// The "interrupt" attribute is used to generate code that is acceptable in
|
||||
// exception-handlers of various kinds. It makes us use a different return
|
||||
// instruction (handled elsewhere) and affects which registers we must return to
|
||||
// our "caller" in the same state as we receive them.
|
||||
|
||||
// For most interrupts, all registers except SP and LR are shared with
|
||||
// user-space. We mark LR to be saved anyway, since this is what the ARM backend
|
||||
// generally does rather than tracking its liveness as a normal register.
|
||||
def CSR_GenericInt : CalleeSavedRegs<(add LR, (sequence "R%u", 12, 0))>;
|
||||
|
||||
// The fast interrupt handlers have more private state and get their own copies
|
||||
// of R8-R12, in addition to SP and LR. As before, mark LR for saving too.
|
||||
|
||||
// FIXME: we mark R11 as callee-saved since it's often the frame-pointer, and
|
||||
// current frame lowering expects to encounter it while processing callee-saved
|
||||
// registers.
|
||||
def CSR_FIQ : CalleeSavedRegs<(add LR, R11, (sequence "R%u", 7, 0))>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ARM Mono calling conventions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CC_ARM_Mono_APCS : CallingConv<[
|
||||
// Mono marks the parameter it wants to pass in this non-abi register with
|
||||
// the 'inreg' attribute.
|
||||
CCIfInReg<CCAssignToReg<[R8]>>,
|
||||
|
||||
CCDelegateTo<CC_ARM_APCS>
|
||||
]>;
|
||||
|
||||
def CC_ARM_Mono_AAPCS : CallingConv<[
|
||||
// Mono marks the parameter it wants to pass in this non-abi register with
|
||||
// the 'inreg' attribute.
|
||||
CCIfInReg<CCAssignToReg<[R8]>>,
|
||||
|
||||
CCDelegateTo<CC_ARM_AAPCS>
|
||||
]>;
|
||||
|
@ -1,81 +0,0 @@
|
||||
//===--- ARMComputeBlockSize.cpp - Compute machine block sizes ------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "ARM.h"
|
||||
#include "ARMBaseInstrInfo.h"
|
||||
#include "ARMBasicBlockInfo.h"
|
||||
#include "ARMMachineFunctionInfo.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace llvm {
|
||||
|
||||
// mayOptimizeThumb2Instruction - Returns true if optimizeThumb2Instructions
|
||||
// below may shrink MI.
|
||||
static bool
|
||||
mayOptimizeThumb2Instruction(const MachineInstr *MI) {
|
||||
switch(MI->getOpcode()) {
|
||||
// optimizeThumb2Instructions.
|
||||
case ARM::t2LEApcrel:
|
||||
case ARM::t2LDRpci:
|
||||
// optimizeThumb2Branches.
|
||||
case ARM::t2B:
|
||||
case ARM::t2Bcc:
|
||||
case ARM::tBcc:
|
||||
// optimizeThumb2JumpTables.
|
||||
case ARM::t2BR_JT:
|
||||
case ARM::tBR_JTr:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void computeBlockSize(MachineFunction *MF, MachineBasicBlock *MBB,
|
||||
BasicBlockInfo &BBI) {
|
||||
const ARMBaseInstrInfo *TII =
|
||||
static_cast<const ARMBaseInstrInfo *>(MF->getSubtarget().getInstrInfo());
|
||||
bool isThumb = MF->getInfo<ARMFunctionInfo>()->isThumbFunction();
|
||||
BBI.Size = 0;
|
||||
BBI.Unalign = 0;
|
||||
BBI.PostAlign = 0;
|
||||
|
||||
for (MachineInstr &I : *MBB) {
|
||||
BBI.Size += TII->getInstSizeInBytes(I);
|
||||
// For inline asm, getInstSizeInBytes returns a conservative estimate.
|
||||
// The actual size may be smaller, but still a multiple of the instr size.
|
||||
if (I.isInlineAsm())
|
||||
BBI.Unalign = isThumb ? 1 : 2;
|
||||
// Also consider instructions that may be shrunk later.
|
||||
else if (isThumb && mayOptimizeThumb2Instruction(&I))
|
||||
BBI.Unalign = 1;
|
||||
}
|
||||
|
||||
// tBR_JTr contains a .align 2 directive.
|
||||
if (!MBB->empty() && MBB->back().getOpcode() == ARM::tBR_JTr) {
|
||||
BBI.PostAlign = 2;
|
||||
MBB->getParent()->ensureAlignment(2);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<BasicBlockInfo> computeAllBlockSizes(MachineFunction *MF) {
|
||||
std::vector<BasicBlockInfo> BBInfo;
|
||||
BBInfo.resize(MF->getNumBlockIDs());
|
||||
|
||||
for (MachineBasicBlock &MBB : *MF)
|
||||
computeBlockSize(MF, &MBB, BBInfo[MBB.getNumber()]);
|
||||
|
||||
return BBInfo;
|
||||
}
|
||||
|
||||
} // end namespace llvm
|
2372
external/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
vendored
2372
external/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
vendored
File diff suppressed because it is too large
Load Diff
@ -1,297 +0,0 @@
|
||||
//===- ARMConstantPoolValue.cpp - ARM constantpool value ------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the ARM specific constantpool value class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "ARMConstantPoolValue.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/IR/Constant.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/GlobalValue.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ARMConstantPoolValue
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
ARMConstantPoolValue::ARMConstantPoolValue(Type *Ty, unsigned id,
|
||||
ARMCP::ARMCPKind kind,
|
||||
unsigned char PCAdj,
|
||||
ARMCP::ARMCPModifier modifier,
|
||||
bool addCurrentAddress)
|
||||
: MachineConstantPoolValue(Ty), LabelId(id), Kind(kind),
|
||||
PCAdjust(PCAdj), Modifier(modifier),
|
||||
AddCurrentAddress(addCurrentAddress) {}
|
||||
|
||||
ARMConstantPoolValue::ARMConstantPoolValue(LLVMContext &C, unsigned id,
|
||||
ARMCP::ARMCPKind kind,
|
||||
unsigned char PCAdj,
|
||||
ARMCP::ARMCPModifier modifier,
|
||||
bool addCurrentAddress)
|
||||
: MachineConstantPoolValue((Type*)Type::getInt32Ty(C)),
|
||||
LabelId(id), Kind(kind), PCAdjust(PCAdj), Modifier(modifier),
|
||||
AddCurrentAddress(addCurrentAddress) {}
|
||||
|
||||
ARMConstantPoolValue::~ARMConstantPoolValue() = default;
|
||||
|
||||
StringRef ARMConstantPoolValue::getModifierText() const {
|
||||
switch (Modifier) {
|
||||
// FIXME: Are these case sensitive? It'd be nice to lower-case all the
|
||||
// strings if that's legal.
|
||||
case ARMCP::no_modifier:
|
||||
return "none";
|
||||
case ARMCP::TLSGD:
|
||||
return "tlsgd";
|
||||
case ARMCP::GOT_PREL:
|
||||
return "GOT_PREL";
|
||||
case ARMCP::GOTTPOFF:
|
||||
return "gottpoff";
|
||||
case ARMCP::TPOFF:
|
||||
return "tpoff";
|
||||
case ARMCP::SBREL:
|
||||
return "SBREL";
|
||||
case ARMCP::SECREL:
|
||||
return "secrel32";
|
||||
}
|
||||
llvm_unreachable("Unknown modifier!");
|
||||
}
|
||||
|
||||
int ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
|
||||
unsigned Alignment) {
|
||||
llvm_unreachable("Shouldn't be calling this directly!");
|
||||
}
|
||||
|
||||
void
|
||||
ARMConstantPoolValue::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
|
||||
ID.AddInteger(LabelId);
|
||||
ID.AddInteger(PCAdjust);
|
||||
}
|
||||
|
||||
bool
|
||||
ARMConstantPoolValue::hasSameValue(ARMConstantPoolValue *ACPV) {
|
||||
if (ACPV->Kind == Kind &&
|
||||
ACPV->PCAdjust == PCAdjust &&
|
||||
ACPV->Modifier == Modifier &&
|
||||
ACPV->LabelId == LabelId &&
|
||||
ACPV->AddCurrentAddress == AddCurrentAddress) {
|
||||
// Two PC relative constpool entries containing the same GV address or
|
||||
// external symbols. FIXME: What about blockaddress?
|
||||
if (Kind == ARMCP::CPValue || Kind == ARMCP::CPExtSymbol)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
||||
LLVM_DUMP_METHOD void ARMConstantPoolValue::dump() const {
|
||||
errs() << " " << *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
void ARMConstantPoolValue::print(raw_ostream &O) const {
|
||||
if (Modifier) O << "(" << getModifierText() << ")";
|
||||
if (PCAdjust != 0) {
|
||||
O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust;
|
||||
if (AddCurrentAddress) O << "-.";
|
||||
O << ")";
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ARMConstantPoolConstant
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
ARMConstantPoolConstant::ARMConstantPoolConstant(Type *Ty,
|
||||
const Constant *C,
|
||||
unsigned ID,
|
||||
ARMCP::ARMCPKind Kind,
|
||||
unsigned char PCAdj,
|
||||
ARMCP::ARMCPModifier Modifier,
|
||||
bool AddCurrentAddress)
|
||||
: ARMConstantPoolValue(Ty, ID, Kind, PCAdj, Modifier, AddCurrentAddress),
|
||||
CVal(C) {}
|
||||
|
||||
ARMConstantPoolConstant::ARMConstantPoolConstant(const Constant *C,
|
||||
unsigned ID,
|
||||
ARMCP::ARMCPKind Kind,
|
||||
unsigned char PCAdj,
|
||||
ARMCP::ARMCPModifier Modifier,
|
||||
bool AddCurrentAddress)
|
||||
: ARMConstantPoolValue((Type*)C->getType(), ID, Kind, PCAdj, Modifier,
|
||||
AddCurrentAddress),
|
||||
CVal(C) {}
|
||||
|
||||
ARMConstantPoolConstant::ARMConstantPoolConstant(const GlobalVariable *GV,
|
||||
const Constant *C)
|
||||
: ARMConstantPoolValue((Type *)C->getType(), 0, ARMCP::CPPromotedGlobal, 0,
|
||||
ARMCP::no_modifier, false), CVal(C) {
|
||||
GVars.insert(GV);
|
||||
}
|
||||
|
||||
ARMConstantPoolConstant *
|
||||
ARMConstantPoolConstant::Create(const Constant *C, unsigned ID) {
|
||||
return new ARMConstantPoolConstant(C, ID, ARMCP::CPValue, 0,
|
||||
ARMCP::no_modifier, false);
|
||||
}
|
||||
|
||||
ARMConstantPoolConstant *
|
||||
ARMConstantPoolConstant::Create(const GlobalVariable *GVar,
|
||||
const Constant *Initializer) {
|
||||
return new ARMConstantPoolConstant(GVar, Initializer);
|
||||
}
|
||||
|
||||
ARMConstantPoolConstant *
|
||||
ARMConstantPoolConstant::Create(const GlobalValue *GV,
|
||||
ARMCP::ARMCPModifier Modifier) {
|
||||
return new ARMConstantPoolConstant((Type*)Type::getInt32Ty(GV->getContext()),
|
||||
GV, 0, ARMCP::CPValue, 0,
|
||||
Modifier, false);
|
||||
}
|
||||
|
||||
ARMConstantPoolConstant *
|
||||
ARMConstantPoolConstant::Create(const Constant *C, unsigned ID,
|
||||
ARMCP::ARMCPKind Kind, unsigned char PCAdj) {
|
||||
return new ARMConstantPoolConstant(C, ID, Kind, PCAdj,
|
||||
ARMCP::no_modifier, false);
|
||||
}
|
||||
|
||||
ARMConstantPoolConstant *
|
||||
ARMConstantPoolConstant::Create(const Constant *C, unsigned ID,
|
||||
ARMCP::ARMCPKind Kind, unsigned char PCAdj,
|
||||
ARMCP::ARMCPModifier Modifier,
|
||||
bool AddCurrentAddress) {
|
||||
return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, Modifier,
|
||||
AddCurrentAddress);
|
||||
}
|
||||
|
||||
const GlobalValue *ARMConstantPoolConstant::getGV() const {
|
||||
return dyn_cast_or_null<GlobalValue>(CVal);
|
||||
}
|
||||
|
||||
const BlockAddress *ARMConstantPoolConstant::getBlockAddress() const {
|
||||
return dyn_cast_or_null<BlockAddress>(CVal);
|
||||
}
|
||||
|
||||
int ARMConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP,
|
||||
unsigned Alignment) {
|
||||
int index =
|
||||
getExistingMachineCPValueImpl<ARMConstantPoolConstant>(CP, Alignment);
|
||||
if (index != -1) {
|
||||
auto *CPV = static_cast<ARMConstantPoolValue*>(
|
||||
CP->getConstants()[index].Val.MachineCPVal);
|
||||
auto *Constant = cast<ARMConstantPoolConstant>(CPV);
|
||||
Constant->GVars.insert(GVars.begin(), GVars.end());
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
bool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) {
|
||||
const ARMConstantPoolConstant *ACPC = dyn_cast<ARMConstantPoolConstant>(ACPV);
|
||||
return ACPC && ACPC->CVal == CVal && ARMConstantPoolValue::hasSameValue(ACPV);
|
||||
}
|
||||
|
||||
void ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
|
||||
ID.AddPointer(CVal);
|
||||
for (const auto *GV : GVars)
|
||||
ID.AddPointer(GV);
|
||||
ARMConstantPoolValue::addSelectionDAGCSEId(ID);
|
||||
}
|
||||
|
||||
void ARMConstantPoolConstant::print(raw_ostream &O) const {
|
||||
O << CVal->getName();
|
||||
ARMConstantPoolValue::print(O);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ARMConstantPoolSymbol
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
ARMConstantPoolSymbol::ARMConstantPoolSymbol(LLVMContext &C, StringRef s,
|
||||
unsigned id, unsigned char PCAdj,
|
||||
ARMCP::ARMCPModifier Modifier,
|
||||
bool AddCurrentAddress)
|
||||
: ARMConstantPoolValue(C, id, ARMCP::CPExtSymbol, PCAdj, Modifier,
|
||||
AddCurrentAddress),
|
||||
S(s) {}
|
||||
|
||||
ARMConstantPoolSymbol *ARMConstantPoolSymbol::Create(LLVMContext &C,
|
||||
StringRef s, unsigned ID,
|
||||
unsigned char PCAdj) {
|
||||
return new ARMConstantPoolSymbol(C, s, ID, PCAdj, ARMCP::no_modifier, false);
|
||||
}
|
||||
|
||||
int ARMConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP,
|
||||
unsigned Alignment) {
|
||||
return getExistingMachineCPValueImpl<ARMConstantPoolSymbol>(CP, Alignment);
|
||||
}
|
||||
|
||||
bool ARMConstantPoolSymbol::hasSameValue(ARMConstantPoolValue *ACPV) {
|
||||
const ARMConstantPoolSymbol *ACPS = dyn_cast<ARMConstantPoolSymbol>(ACPV);
|
||||
return ACPS && ACPS->S == S && ARMConstantPoolValue::hasSameValue(ACPV);
|
||||
}
|
||||
|
||||
void ARMConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
|
||||
ID.AddString(S);
|
||||
ARMConstantPoolValue::addSelectionDAGCSEId(ID);
|
||||
}
|
||||
|
||||
void ARMConstantPoolSymbol::print(raw_ostream &O) const {
|
||||
O << S;
|
||||
ARMConstantPoolValue::print(O);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ARMConstantPoolMBB
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
ARMConstantPoolMBB::ARMConstantPoolMBB(LLVMContext &C,
|
||||
const MachineBasicBlock *mbb,
|
||||
unsigned id, unsigned char PCAdj,
|
||||
ARMCP::ARMCPModifier Modifier,
|
||||
bool AddCurrentAddress)
|
||||
: ARMConstantPoolValue(C, id, ARMCP::CPMachineBasicBlock, PCAdj,
|
||||
Modifier, AddCurrentAddress),
|
||||
MBB(mbb) {}
|
||||
|
||||
ARMConstantPoolMBB *ARMConstantPoolMBB::Create(LLVMContext &C,
|
||||
const MachineBasicBlock *mbb,
|
||||
unsigned ID,
|
||||
unsigned char PCAdj) {
|
||||
return new ARMConstantPoolMBB(C, mbb, ID, PCAdj, ARMCP::no_modifier, false);
|
||||
}
|
||||
|
||||
int ARMConstantPoolMBB::getExistingMachineCPValue(MachineConstantPool *CP,
|
||||
unsigned Alignment) {
|
||||
return getExistingMachineCPValueImpl<ARMConstantPoolMBB>(CP, Alignment);
|
||||
}
|
||||
|
||||
bool ARMConstantPoolMBB::hasSameValue(ARMConstantPoolValue *ACPV) {
|
||||
const ARMConstantPoolMBB *ACPMBB = dyn_cast<ARMConstantPoolMBB>(ACPV);
|
||||
return ACPMBB && ACPMBB->MBB == MBB &&
|
||||
ARMConstantPoolValue::hasSameValue(ACPV);
|
||||
}
|
||||
|
||||
void ARMConstantPoolMBB::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
|
||||
ID.AddPointer(MBB);
|
||||
ARMConstantPoolValue::addSelectionDAGCSEId(ID);
|
||||
}
|
||||
|
||||
void ARMConstantPoolMBB::print(raw_ostream &O) const {
|
||||
O << printMBBReference(*MBB);
|
||||
ARMConstantPoolValue::print(O);
|
||||
}
|
284
external/llvm/lib/Target/ARM/ARMConstantPoolValue.h
vendored
284
external/llvm/lib/Target/ARM/ARMConstantPoolValue.h
vendored
@ -1,284 +0,0 @@
|
||||
//===- ARMConstantPoolValue.h - ARM constantpool value ----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the ARM specific constantpool value class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H
|
||||
#define LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H
|
||||
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/CodeGen/MachineConstantPool.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class BlockAddress;
|
||||
class Constant;
|
||||
class GlobalValue;
|
||||
class GlobalVariable;
|
||||
class LLVMContext;
|
||||
class MachineBasicBlock;
|
||||
class raw_ostream;
|
||||
class Type;
|
||||
|
||||
namespace ARMCP {
|
||||
|
||||
enum ARMCPKind {
|
||||
CPValue,
|
||||
CPExtSymbol,
|
||||
CPBlockAddress,
|
||||
CPLSDA,
|
||||
CPMachineBasicBlock,
|
||||
CPPromotedGlobal
|
||||
};
|
||||
|
||||
enum ARMCPModifier {
|
||||
no_modifier, /// None
|
||||
TLSGD, /// Thread Local Storage (General Dynamic Mode)
|
||||
GOT_PREL, /// Global Offset Table, PC Relative
|
||||
GOTTPOFF, /// Global Offset Table, Thread Pointer Offset
|
||||
TPOFF, /// Thread Pointer Offset
|
||||
SECREL, /// Section Relative (Windows TLS)
|
||||
SBREL, /// Static Base Relative (RWPI)
|
||||
};
|
||||
|
||||
} // end namespace ARMCP
|
||||
|
||||
/// ARMConstantPoolValue - ARM specific constantpool value. This is used to
|
||||
/// represent PC-relative displacement between the address of the load
|
||||
/// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)).
|
||||
class ARMConstantPoolValue : public MachineConstantPoolValue {
|
||||
unsigned LabelId; // Label id of the load.
|
||||
ARMCP::ARMCPKind Kind; // Kind of constant.
|
||||
unsigned char PCAdjust; // Extra adjustment if constantpool is pc-relative.
|
||||
// 8 for ARM, 4 for Thumb.
|
||||
ARMCP::ARMCPModifier Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8))
|
||||
bool AddCurrentAddress;
|
||||
|
||||
protected:
|
||||
ARMConstantPoolValue(Type *Ty, unsigned id, ARMCP::ARMCPKind Kind,
|
||||
unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
|
||||
bool AddCurrentAddress);
|
||||
|
||||
ARMConstantPoolValue(LLVMContext &C, unsigned id, ARMCP::ARMCPKind Kind,
|
||||
unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
|
||||
bool AddCurrentAddress);
|
||||
|
||||
template <typename Derived>
|
||||
int getExistingMachineCPValueImpl(MachineConstantPool *CP,
|
||||
unsigned Alignment) {
|
||||
unsigned AlignMask = Alignment - 1;
|
||||
const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants();
|
||||
for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
|
||||
if (Constants[i].isMachineConstantPoolEntry() &&
|
||||
(Constants[i].getAlignment() & AlignMask) == 0) {
|
||||
auto *CPV =
|
||||
static_cast<ARMConstantPoolValue*>(Constants[i].Val.MachineCPVal);
|
||||
if (Derived *APC = dyn_cast<Derived>(CPV))
|
||||
if (cast<Derived>(this)->equals(APC))
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public:
|
||||
~ARMConstantPoolValue() override;
|
||||
|
||||
ARMCP::ARMCPModifier getModifier() const { return Modifier; }
|
||||
StringRef getModifierText() const;
|
||||
bool hasModifier() const { return Modifier != ARMCP::no_modifier; }
|
||||
|
||||
bool mustAddCurrentAddress() const { return AddCurrentAddress; }
|
||||
|
||||
unsigned getLabelId() const { return LabelId; }
|
||||
unsigned char getPCAdjustment() const { return PCAdjust; }
|
||||
|
||||
bool isGlobalValue() const { return Kind == ARMCP::CPValue; }
|
||||
bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; }
|
||||
bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; }
|
||||
bool isLSDA() const { return Kind == ARMCP::CPLSDA; }
|
||||
bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; }
|
||||
bool isPromotedGlobal() const{ return Kind == ARMCP::CPPromotedGlobal; }
|
||||
|
||||
int getExistingMachineCPValue(MachineConstantPool *CP,
|
||||
unsigned Alignment) override;
|
||||
|
||||
void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
|
||||
|
||||
/// hasSameValue - Return true if this ARM constpool value can share the same
|
||||
/// constantpool entry as another ARM constpool value.
|
||||
virtual bool hasSameValue(ARMConstantPoolValue *ACPV);
|
||||
|
||||
bool equals(const ARMConstantPoolValue *A) const {
|
||||
return this->LabelId == A->LabelId &&
|
||||
this->PCAdjust == A->PCAdjust &&
|
||||
this->Modifier == A->Modifier;
|
||||
}
|
||||
|
||||
void print(raw_ostream &O) const override;
|
||||
void print(raw_ostream *O) const { if (O) print(*O); }
|
||||
void dump() const;
|
||||
};
|
||||
|
||||
inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) {
|
||||
V.print(O);
|
||||
return O;
|
||||
}
|
||||
|
||||
/// ARMConstantPoolConstant - ARM-specific constant pool values for Constants,
|
||||
/// Functions, and BlockAddresses.
|
||||
class ARMConstantPoolConstant : public ARMConstantPoolValue {
|
||||
const Constant *CVal; // Constant being loaded.
|
||||
SmallPtrSet<const GlobalVariable*, 1> GVars;
|
||||
|
||||
ARMConstantPoolConstant(const Constant *C,
|
||||
unsigned ID,
|
||||
ARMCP::ARMCPKind Kind,
|
||||
unsigned char PCAdj,
|
||||
ARMCP::ARMCPModifier Modifier,
|
||||
bool AddCurrentAddress);
|
||||
ARMConstantPoolConstant(Type *Ty, const Constant *C,
|
||||
unsigned ID,
|
||||
ARMCP::ARMCPKind Kind,
|
||||
unsigned char PCAdj,
|
||||
ARMCP::ARMCPModifier Modifier,
|
||||
bool AddCurrentAddress);
|
||||
ARMConstantPoolConstant(const GlobalVariable *GV, const Constant *Init);
|
||||
|
||||
public:
|
||||
static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID);
|
||||
static ARMConstantPoolConstant *Create(const GlobalValue *GV,
|
||||
ARMCP::ARMCPModifier Modifier);
|
||||
static ARMConstantPoolConstant *Create(const GlobalVariable *GV,
|
||||
const Constant *Initializer);
|
||||
static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
|
||||
ARMCP::ARMCPKind Kind,
|
||||
unsigned char PCAdj);
|
||||
static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
|
||||
ARMCP::ARMCPKind Kind,
|
||||
unsigned char PCAdj,
|
||||
ARMCP::ARMCPModifier Modifier,
|
||||
bool AddCurrentAddress);
|
||||
|
||||
const GlobalValue *getGV() const;
|
||||
const BlockAddress *getBlockAddress() const;
|
||||
|
||||
using promoted_iterator = SmallPtrSet<const GlobalVariable *, 1>::iterator;
|
||||
|
||||
iterator_range<promoted_iterator> promotedGlobals() {
|
||||
return iterator_range<promoted_iterator>(GVars.begin(), GVars.end());
|
||||
}
|
||||
|
||||
const Constant *getPromotedGlobalInit() const {
|
||||
return CVal;
|
||||
}
|
||||
|
||||
int getExistingMachineCPValue(MachineConstantPool *CP,
|
||||
unsigned Alignment) override;
|
||||
|
||||
/// hasSameValue - Return true if this ARM constpool value can share the same
|
||||
/// constantpool entry as another ARM constpool value.
|
||||
bool hasSameValue(ARMConstantPoolValue *ACPV) override;
|
||||
|
||||
void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
|
||||
|
||||
void print(raw_ostream &O) const override;
|
||||
|
||||
static bool classof(const ARMConstantPoolValue *APV) {
|
||||
return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA() ||
|
||||
APV->isPromotedGlobal();
|
||||
}
|
||||
|
||||
bool equals(const ARMConstantPoolConstant *A) const {
|
||||
return CVal == A->CVal && ARMConstantPoolValue::equals(A);
|
||||
}
|
||||
};
|
||||
|
||||
/// ARMConstantPoolSymbol - ARM-specific constantpool values for external
|
||||
/// symbols.
|
||||
class ARMConstantPoolSymbol : public ARMConstantPoolValue {
|
||||
const std::string S; // ExtSymbol being loaded.
|
||||
|
||||
ARMConstantPoolSymbol(LLVMContext &C, StringRef s, unsigned id,
|
||||
unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
|
||||
bool AddCurrentAddress);
|
||||
|
||||
public:
|
||||
static ARMConstantPoolSymbol *Create(LLVMContext &C, StringRef s, unsigned ID,
|
||||
unsigned char PCAdj);
|
||||
|
||||
StringRef getSymbol() const { return S; }
|
||||
|
||||
int getExistingMachineCPValue(MachineConstantPool *CP,
|
||||
unsigned Alignment) override;
|
||||
|
||||
void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
|
||||
|
||||
/// hasSameValue - Return true if this ARM constpool value can share the same
|
||||
/// constantpool entry as another ARM constpool value.
|
||||
bool hasSameValue(ARMConstantPoolValue *ACPV) override;
|
||||
|
||||
void print(raw_ostream &O) const override;
|
||||
|
||||
static bool classof(const ARMConstantPoolValue *ACPV) {
|
||||
return ACPV->isExtSymbol();
|
||||
}
|
||||
|
||||
bool equals(const ARMConstantPoolSymbol *A) const {
|
||||
return S == A->S && ARMConstantPoolValue::equals(A);
|
||||
}
|
||||
};
|
||||
|
||||
/// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic
|
||||
/// block.
|
||||
class ARMConstantPoolMBB : public ARMConstantPoolValue {
|
||||
const MachineBasicBlock *MBB; // Machine basic block.
|
||||
|
||||
ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id,
|
||||
unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
|
||||
bool AddCurrentAddress);
|
||||
|
||||
public:
|
||||
static ARMConstantPoolMBB *Create(LLVMContext &C,
|
||||
const MachineBasicBlock *mbb,
|
||||
unsigned ID, unsigned char PCAdj);
|
||||
|
||||
const MachineBasicBlock *getMBB() const { return MBB; }
|
||||
|
||||
int getExistingMachineCPValue(MachineConstantPool *CP,
|
||||
unsigned Alignment) override;
|
||||
|
||||
void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
|
||||
|
||||
/// hasSameValue - Return true if this ARM constpool value can share the same
|
||||
/// constantpool entry as another ARM constpool value.
|
||||
bool hasSameValue(ARMConstantPoolValue *ACPV) override;
|
||||
|
||||
void print(raw_ostream &O) const override;
|
||||
|
||||
static bool classof(const ARMConstantPoolValue *ACPV) {
|
||||
return ACPV->isMachineBasicBlock();
|
||||
}
|
||||
|
||||
bool equals(const ARMConstantPoolMBB *A) const {
|
||||
return MBB == A->MBB && ARMConstantPoolValue::equals(A);
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H
|
1738
external/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
vendored
1738
external/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
vendored
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
||||
60048d4453d8926a42564cda5d2a0a0c2401c4bd
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user