2015-07-30 06:32:47 +08:00
|
|
|
//===-- ARMMachineFunctionInfo.h - ARM machine function info ----*- C++ -*-===//
|
2009-08-11 23:33:49 +08:00
|
|
|
//
|
2007-01-19 15:51:42 +08:00
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-30 04:36:04 +08:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2009-08-11 23:33:49 +08:00
|
|
|
//
|
2007-01-19 15:51:42 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file declares ARM-specific per-machine-function information.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2014-08-14 00:26:38 +08:00
|
|
|
#ifndef LLVM_LIB_TARGET_ARM_ARMMACHINEFUNCTIONINFO_H
|
|
|
|
#define LLVM_LIB_TARGET_ARM_ARMMACHINEFUNCTIONINFO_H
|
2007-01-19 15:51:42 +08:00
|
|
|
|
2015-01-14 19:23:27 +08:00
|
|
|
#include "llvm/ADT/DenseMap.h"
|
2017-01-27 07:40:06 +08:00
|
|
|
#include "llvm/ADT/SmallPtrSet.h"
|
2007-01-19 15:51:42 +08:00
|
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
2017-01-27 07:40:06 +08:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
|
|
#include <utility>
|
2007-01-19 15:51:42 +08:00
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
|
2011-01-15 08:09:18 +08:00
|
|
|
/// ARMFunctionInfo - This class is derived from MachineFunctionInfo and
|
|
|
|
/// contains private ARM-specific information for each MachineFunction.
|
2007-01-19 15:51:42 +08:00
|
|
|
class ARMFunctionInfo : public MachineFunctionInfo {
|
2011-12-20 10:50:00 +08:00
|
|
|
virtual void anchor();
|
2007-01-19 15:51:42 +08:00
|
|
|
|
|
|
|
/// isThumb - True if this function is compiled under Thumb mode.
|
2007-04-24 04:07:25 +08:00
|
|
|
/// Used to initialized Align, so must precede it.
|
2017-01-27 07:40:06 +08:00
|
|
|
bool isThumb = false;
|
2007-01-19 15:51:42 +08:00
|
|
|
|
2009-07-01 02:04:13 +08:00
|
|
|
/// hasThumb2 - True if the target architecture supports Thumb2. Do not use
|
|
|
|
/// to determine if function is compiled under Thumb mode, for that use
|
|
|
|
/// 'isThumb'.
|
2017-01-27 07:40:06 +08:00
|
|
|
bool hasThumb2 = false;
|
2009-07-01 02:04:13 +08:00
|
|
|
|
2013-05-20 16:01:34 +08:00
|
|
|
/// StByValParamsPadding - For parameter that is split between
|
|
|
|
/// GPRs and memory; while recovering GPRs part, when
|
Use 16 byte stack alignment for NaCl on ARM
NaCl's ARM ABI uses 16 byte stack alignment, so set that in
ARMSubtarget.cpp.
Using 16 byte alignment exposes an issue in code generation in which a
varargs function leaves a 4 byte gap between the values of r1-r3 saved
to the stack and the following arguments that were passed on the
stack. (Previously, this code only needed to support 4 byte and 8
byte alignment.)
With this issue, llc generated:
varargs_func:
sub sp, sp, #16
push {lr}
sub sp, sp, #12
add r0, sp, #16 // Should be 20
stm r0, {r1, r2, r3}
ldr r0, .LCPI0_0 // Address of va_list
add r1, sp, #16
str r1, [r0]
bl external_func
Fix the bug by checking for "Align > 4". Also simplify the code by
using OffsetToAlignment(), and update comments.
Differential Revision: http://llvm-reviews.chandlerc.com/D2677
llvm-svn: 201497
2014-02-17 02:59:48 +08:00
|
|
|
/// StackAlignment > 4, and GPRs-part-size mod StackAlignment != 0,
|
2013-05-20 16:01:34 +08:00
|
|
|
/// we need to insert gap before parameter start address. It allows to
|
|
|
|
/// "attach" GPR-part to the part that was passed via stack.
|
2017-01-27 07:40:06 +08:00
|
|
|
unsigned StByValParamsPadding = 0;
|
2013-05-20 16:01:34 +08:00
|
|
|
|
2007-01-19 15:51:42 +08:00
|
|
|
/// VarArgsRegSaveSize - Size of the register save area for vararg functions.
|
|
|
|
///
|
2017-01-27 07:40:06 +08:00
|
|
|
unsigned ArgRegsSaveSize = 0;
|
2007-01-19 15:51:42 +08:00
|
|
|
|
2014-08-06 05:32:21 +08:00
|
|
|
/// ReturnRegsCount - Number of registers used up in the return.
|
2017-01-27 07:40:06 +08:00
|
|
|
unsigned ReturnRegsCount = 0;
|
2014-08-06 05:32:21 +08:00
|
|
|
|
2007-01-20 10:09:25 +08:00
|
|
|
/// HasStackFrame - True if this function has a stack frame. Set by
|
2015-07-15 07:06:07 +08:00
|
|
|
/// determineCalleeSaves().
|
2017-01-27 07:40:06 +08:00
|
|
|
bool HasStackFrame = false;
|
2007-01-19 15:51:42 +08:00
|
|
|
|
2010-08-11 03:30:19 +08:00
|
|
|
/// RestoreSPFromFP - True if epilogue should restore SP from FP. Set by
|
|
|
|
/// emitPrologue.
|
2017-01-27 07:40:06 +08:00
|
|
|
bool RestoreSPFromFP = false;
|
2010-08-11 03:30:19 +08:00
|
|
|
|
2007-03-01 16:26:31 +08:00
|
|
|
/// LRSpilledForFarJump - True if the LR register has been for spilled to
|
|
|
|
/// enable far jump.
|
2017-01-27 07:40:06 +08:00
|
|
|
bool LRSpilledForFarJump = false;
|
2007-01-30 06:22:24 +08:00
|
|
|
|
2007-01-20 10:09:25 +08:00
|
|
|
/// FramePtrSpillOffset - If HasStackFrame, this records the frame pointer
|
2007-01-19 15:51:42 +08:00
|
|
|
/// spill stack offset.
|
2017-01-27 07:40:06 +08:00
|
|
|
unsigned FramePtrSpillOffset = 0;
|
2007-01-19 15:51:42 +08:00
|
|
|
|
2010-11-03 01:35:25 +08:00
|
|
|
/// GPRCS1Offset, GPRCS2Offset, DPRCSOffset - Starting offset of callee saved
|
|
|
|
/// register spills areas. For Mac OS X:
|
2007-01-19 15:51:42 +08:00
|
|
|
///
|
2010-11-03 01:35:25 +08:00
|
|
|
/// GPR callee-saved (1) : r4, r5, r6, r7, lr
|
|
|
|
/// --------------------------------------------
|
|
|
|
/// GPR callee-saved (2) : r8, r10, r11
|
2007-01-19 15:51:42 +08:00
|
|
|
/// --------------------------------------------
|
|
|
|
/// DPR callee-saved : d8 - d15
|
2011-12-23 08:36:18 +08:00
|
|
|
///
|
|
|
|
/// Also see AlignedDPRCSRegs below. Not all D-regs need to go in area 3.
|
|
|
|
/// Some may be spilled after the stack has been realigned.
|
2017-01-27 07:40:06 +08:00
|
|
|
unsigned GPRCS1Offset = 0;
|
|
|
|
unsigned GPRCS2Offset = 0;
|
|
|
|
unsigned DPRCSOffset = 0;
|
2007-01-19 15:51:42 +08:00
|
|
|
|
2010-11-03 01:35:25 +08:00
|
|
|
/// GPRCS1Size, GPRCS2Size, DPRCSSize - Sizes of callee saved register spills
|
|
|
|
/// areas.
|
2017-01-27 07:40:06 +08:00
|
|
|
unsigned GPRCS1Size = 0;
|
|
|
|
unsigned GPRCS2Size = 0;
|
|
|
|
unsigned DPRCSAlignGapSize = 0;
|
|
|
|
unsigned DPRCSSize = 0;
|
2007-01-19 15:51:42 +08:00
|
|
|
|
2011-12-23 08:36:18 +08:00
|
|
|
/// NumAlignedDPRCS2Regs - The number of callee-saved DPRs that are saved in
|
|
|
|
/// the aligned portion of the stack frame. This is always a contiguous
|
|
|
|
/// sequence of D-registers starting from d8.
|
|
|
|
///
|
|
|
|
/// We do not keep track of the frame indices used for these registers - they
|
|
|
|
/// behave like any other frame index in the aligned stack frame. These
|
|
|
|
/// registers also aren't included in DPRCSSize above.
|
2017-01-27 07:40:06 +08:00
|
|
|
unsigned NumAlignedDPRCS2Regs = 0;
|
2011-12-23 08:36:18 +08:00
|
|
|
|
2017-01-27 07:40:06 +08:00
|
|
|
unsigned PICLabelUId = 0;
|
2008-11-08 08:51:41 +08:00
|
|
|
|
2010-04-17 22:41:14 +08:00
|
|
|
/// VarArgsFrameIndex - FrameIndex for start of varargs area.
|
2017-01-27 07:40:06 +08:00
|
|
|
int VarArgsFrameIndex = 0;
|
2010-04-17 22:41:14 +08:00
|
|
|
|
2010-06-19 07:09:54 +08:00
|
|
|
/// HasITBlocks - True if IT blocks have been inserted.
|
2017-01-27 07:40:06 +08:00
|
|
|
bool HasITBlocks = false;
|
2010-06-19 07:09:54 +08:00
|
|
|
|
2011-01-31 06:07:39 +08:00
|
|
|
/// CPEClones - Track constant pool entries clones created by Constant Island
|
|
|
|
/// pass.
|
|
|
|
DenseMap<unsigned, unsigned> CPEClones;
|
|
|
|
|
2014-04-03 00:10:33 +08:00
|
|
|
/// ArgumentStackSize - amount of bytes on stack consumed by the arguments
|
|
|
|
/// being passed on the stack
|
2017-01-27 07:40:06 +08:00
|
|
|
unsigned ArgumentStackSize = 0;
|
2014-04-03 00:10:33 +08:00
|
|
|
|
2014-07-16 01:18:41 +08:00
|
|
|
/// CoalescedWeights - mapping of basic blocks to the rolling counter of
|
|
|
|
/// coalesced weights.
|
|
|
|
DenseMap<const MachineBasicBlock*, unsigned> CoalescedWeights;
|
|
|
|
|
2016-01-12 08:47:18 +08:00
|
|
|
/// True if this function has a subset of CSRs that is handled explicitly via
|
|
|
|
/// copies.
|
2017-01-27 07:40:06 +08:00
|
|
|
bool IsSplitCSR = false;
|
2016-01-12 08:47:18 +08:00
|
|
|
|
2016-09-26 15:26:24 +08:00
|
|
|
/// Globals that have had their storage promoted into the constant pool.
|
|
|
|
SmallPtrSet<const GlobalVariable*,2> PromotedGlobals;
|
|
|
|
|
|
|
|
/// The amount the literal pool has been increasedby due to promoted globals.
|
2017-01-27 07:40:06 +08:00
|
|
|
int PromotedGlobalsIncrease = 0;
|
2018-07-31 03:41:25 +08:00
|
|
|
|
2007-01-19 15:51:42 +08:00
|
|
|
public:
|
2017-01-27 07:40:06 +08:00
|
|
|
ARMFunctionInfo() = default;
|
2007-01-19 15:51:42 +08:00
|
|
|
|
2014-06-19 06:48:09 +08:00
|
|
|
explicit ARMFunctionInfo(MachineFunction &MF);
|
2007-01-19 15:51:42 +08:00
|
|
|
|
|
|
|
bool isThumbFunction() const { return isThumb; }
|
2009-07-09 07:10:31 +08:00
|
|
|
bool isThumb1OnlyFunction() const { return isThumb && !hasThumb2; }
|
2009-07-01 02:04:13 +08:00
|
|
|
bool isThumb2Function() const { return isThumb && hasThumb2; }
|
2007-01-19 15:51:42 +08:00
|
|
|
|
2013-05-20 16:01:34 +08:00
|
|
|
unsigned getStoredByValParamsPadding() const { return StByValParamsPadding; }
|
|
|
|
void setStoredByValParamsPadding(unsigned p) { StByValParamsPadding = p; }
|
|
|
|
|
2015-03-12 02:54:22 +08:00
|
|
|
unsigned getArgRegsSaveSize() const { return ArgRegsSaveSize; }
|
2013-04-30 15:19:58 +08:00
|
|
|
void setArgRegsSaveSize(unsigned s) { ArgRegsSaveSize = s; }
|
2007-01-19 15:51:42 +08:00
|
|
|
|
2014-08-06 05:32:21 +08:00
|
|
|
unsigned getReturnRegsCount() const { return ReturnRegsCount; }
|
|
|
|
void setReturnRegsCount(unsigned s) { ReturnRegsCount = s; }
|
|
|
|
|
2007-01-20 10:09:25 +08:00
|
|
|
bool hasStackFrame() const { return HasStackFrame; }
|
|
|
|
void setHasStackFrame(bool s) { HasStackFrame = s; }
|
2007-01-30 06:22:24 +08:00
|
|
|
|
2010-08-11 03:30:19 +08:00
|
|
|
bool shouldRestoreSPFromFP() const { return RestoreSPFromFP; }
|
|
|
|
void setShouldRestoreSPFromFP(bool s) { RestoreSPFromFP = s; }
|
|
|
|
|
2007-03-01 16:26:31 +08:00
|
|
|
bool isLRSpilledForFarJump() const { return LRSpilledForFarJump; }
|
|
|
|
void setLRIsSpilledForFarJump(bool s) { LRSpilledForFarJump = s; }
|
2007-01-30 06:22:24 +08:00
|
|
|
|
2007-01-19 15:51:42 +08:00
|
|
|
unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; }
|
|
|
|
void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; }
|
2009-08-11 23:33:49 +08:00
|
|
|
|
2011-12-23 08:36:18 +08:00
|
|
|
unsigned getNumAlignedDPRCS2Regs() const { return NumAlignedDPRCS2Regs; }
|
|
|
|
void setNumAlignedDPRCS2Regs(unsigned n) { NumAlignedDPRCS2Regs = n; }
|
|
|
|
|
2010-11-03 01:35:25 +08:00
|
|
|
unsigned getGPRCalleeSavedArea1Offset() const { return GPRCS1Offset; }
|
|
|
|
unsigned getGPRCalleeSavedArea2Offset() const { return GPRCS2Offset; }
|
2007-01-19 15:51:42 +08:00
|
|
|
unsigned getDPRCalleeSavedAreaOffset() const { return DPRCSOffset; }
|
|
|
|
|
2010-11-03 01:35:25 +08:00
|
|
|
void setGPRCalleeSavedArea1Offset(unsigned o) { GPRCS1Offset = o; }
|
|
|
|
void setGPRCalleeSavedArea2Offset(unsigned o) { GPRCS2Offset = o; }
|
2007-01-19 15:51:42 +08:00
|
|
|
void setDPRCalleeSavedAreaOffset(unsigned o) { DPRCSOffset = o; }
|
|
|
|
|
2010-11-03 01:35:25 +08:00
|
|
|
unsigned getGPRCalleeSavedArea1Size() const { return GPRCS1Size; }
|
|
|
|
unsigned getGPRCalleeSavedArea2Size() const { return GPRCS2Size; }
|
2014-11-05 08:27:13 +08:00
|
|
|
unsigned getDPRCalleeSavedGapSize() const { return DPRCSAlignGapSize; }
|
2007-01-19 15:51:42 +08:00
|
|
|
unsigned getDPRCalleeSavedAreaSize() const { return DPRCSSize; }
|
|
|
|
|
2010-11-03 01:35:25 +08:00
|
|
|
void setGPRCalleeSavedArea1Size(unsigned s) { GPRCS1Size = s; }
|
|
|
|
void setGPRCalleeSavedArea2Size(unsigned s) { GPRCS2Size = s; }
|
2014-11-05 08:27:13 +08:00
|
|
|
void setDPRCalleeSavedGapSize(unsigned s) { DPRCSAlignGapSize = s; }
|
2007-01-19 15:51:42 +08:00
|
|
|
void setDPRCalleeSavedAreaSize(unsigned s) { DPRCSSize = s; }
|
|
|
|
|
2014-04-03 00:10:33 +08:00
|
|
|
unsigned getArgumentStackSize() const { return ArgumentStackSize; }
|
|
|
|
void setArgumentStackSize(unsigned size) { ArgumentStackSize = size; }
|
|
|
|
|
2011-01-17 16:03:18 +08:00
|
|
|
void initPICLabelUId(unsigned UId) {
|
|
|
|
PICLabelUId = UId;
|
2008-11-08 08:51:41 +08:00
|
|
|
}
|
|
|
|
|
2011-01-17 16:03:18 +08:00
|
|
|
unsigned getNumPICLabels() const {
|
|
|
|
return PICLabelUId;
|
2008-11-08 08:51:41 +08:00
|
|
|
}
|
|
|
|
|
2011-01-17 16:03:18 +08:00
|
|
|
unsigned createPICLabelUId() {
|
|
|
|
return PICLabelUId++;
|
2008-11-08 08:51:41 +08:00
|
|
|
}
|
2010-04-17 22:41:14 +08:00
|
|
|
|
|
|
|
int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
|
|
|
|
void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
|
2010-06-19 07:09:54 +08:00
|
|
|
|
|
|
|
bool hasITBlocks() const { return HasITBlocks; }
|
|
|
|
void setHasITBlocks(bool h) { HasITBlocks = h; }
|
2011-01-31 06:07:39 +08:00
|
|
|
|
2016-01-12 08:47:18 +08:00
|
|
|
bool isSplitCSR() const { return IsSplitCSR; }
|
|
|
|
void setIsSplitCSR(bool s) { IsSplitCSR = s; }
|
|
|
|
|
2011-01-31 06:07:39 +08:00
|
|
|
void recordCPEClone(unsigned CPIdx, unsigned CPCloneIdx) {
|
|
|
|
if (!CPEClones.insert(std::make_pair(CPCloneIdx, CPIdx)).second)
|
2014-06-18 13:05:13 +08:00
|
|
|
llvm_unreachable("Duplicate entries!");
|
2011-01-31 06:07:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
unsigned getOriginalCPIdx(unsigned CloneIdx) const {
|
|
|
|
DenseMap<unsigned, unsigned>::const_iterator I = CPEClones.find(CloneIdx);
|
|
|
|
if (I != CPEClones.end())
|
|
|
|
return I->second;
|
|
|
|
else
|
|
|
|
return -1U;
|
|
|
|
}
|
2014-07-16 01:18:41 +08:00
|
|
|
|
|
|
|
DenseMap<const MachineBasicBlock*, unsigned>::iterator getCoalescedWeight(
|
|
|
|
MachineBasicBlock* MBB) {
|
|
|
|
auto It = CoalescedWeights.find(MBB);
|
|
|
|
if (It == CoalescedWeights.end()) {
|
|
|
|
It = CoalescedWeights.insert(std::make_pair(MBB, 0)).first;
|
|
|
|
}
|
|
|
|
return It;
|
|
|
|
}
|
2016-09-26 15:26:24 +08:00
|
|
|
|
|
|
|
/// Indicate to the backend that \c GV has had its storage changed to inside
|
|
|
|
/// a constant pool. This means it no longer needs to be emitted as a
|
|
|
|
/// global variable.
|
|
|
|
void markGlobalAsPromotedToConstantPool(const GlobalVariable *GV) {
|
|
|
|
PromotedGlobals.insert(GV);
|
|
|
|
}
|
|
|
|
SmallPtrSet<const GlobalVariable*, 2>& getGlobalsPromotedToConstantPool() {
|
|
|
|
return PromotedGlobals;
|
|
|
|
}
|
|
|
|
int getPromotedConstpoolIncrease() const {
|
|
|
|
return PromotedGlobalsIncrease;
|
|
|
|
}
|
|
|
|
void setPromotedConstpoolIncrease(int Sz) {
|
|
|
|
PromotedGlobalsIncrease = Sz;
|
|
|
|
}
|
2007-01-19 15:51:42 +08:00
|
|
|
};
|
|
|
|
|
2017-01-27 07:40:06 +08:00
|
|
|
} // end namespace llvm
|
|
|
|
|
|
|
|
#endif // LLVM_LIB_TARGET_ARM_ARMMACHINEFUNCTIONINFO_H
|