summaryrefslogtreecommitdiff
path: root/include/llvm/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/CodeGen')
-rw-r--r--include/llvm/CodeGen/MachineFrameInfo.h11
-rw-r--r--include/llvm/CodeGen/MachineFunction.h9
-rw-r--r--include/llvm/CodeGen/MachineOperand.h17
-rw-r--r--include/llvm/CodeGen/Passes.h5
-rw-r--r--include/llvm/CodeGen/StackMapLivenessAnalysis.h67
-rw-r--r--include/llvm/CodeGen/StackMaps.h32
6 files changed, 136 insertions, 5 deletions
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
index 747938f3f9..163a9154c6 100644
--- a/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -145,6 +145,10 @@ class MachineFrameInfo {
/// to builtin \@llvm.returnaddress.
bool ReturnAddressTaken;
+ /// HasStackmap - This boolean keeps track of whether there is a call
+ /// to builtin \@llvm.experimental.stackmap or \@llvm.experimental.patchpoint.
+ bool HasStackMap;
+
/// StackSize - The prolog/epilog code inserter calculates the final stack
/// offsets for all of the fixed size objects, updating the Objects list
/// above. It then updates StackSize to contain the number of bytes that need
@@ -235,6 +239,7 @@ public:
HasVarSizedObjects = false;
FrameAddressTaken = false;
ReturnAddressTaken = false;
+ HasStackMap = false;
AdjustsStack = false;
HasCalls = false;
StackProtectorIdx = -1;
@@ -280,6 +285,12 @@ public:
bool isReturnAddressTaken() const { return ReturnAddressTaken; }
void setReturnAddressIsTaken(bool s) { ReturnAddressTaken = s; }
+ /// hasStackMap - This method may be called any time after instruction
+ /// selection is complete to determine if there is a call to builtin
+ /// \@llvm.experimental.stackmap or \@llvm.experimental.patchpoint.
+ bool hasStackMap() const { return HasStackMap; }
+ void setHasStackMap(bool s = true) { HasStackMap = s; }
+
/// getObjectIndexBegin - Return the minimum frame object index.
///
int getObjectIndexBegin() const { return -NumFixedObjects; }
diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h
index 43b370cccf..09cc1e5dfb 100644
--- a/include/llvm/CodeGen/MachineFunction.h
+++ b/include/llvm/CodeGen/MachineFunction.h
@@ -426,6 +426,15 @@ public:
OperandRecycler.deallocate(Cap, Array);
}
+ /// \brief Allocate and initialize a register mask with @p NumRegister bits.
+ uint32_t *allocateRegisterMask(unsigned NumRegister) {
+ unsigned Size = (NumRegister + 31) / 32;
+ uint32_t *Mask = Allocator.Allocate<uint32_t>(Size);
+ for (unsigned i = 0; i != Size; ++i)
+ Mask[i] = 0;
+ return Mask;
+ }
+
/// allocateMemRefsArray - Allocate an array to hold MachineMemOperand
/// pointers. This array is owned by the MachineFunction.
MachineInstr::mmo_iterator allocateMemRefsArray(unsigned long Num);
diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h
index 40f3580bfd..c2a0f65666 100644
--- a/include/llvm/CodeGen/MachineOperand.h
+++ b/include/llvm/CodeGen/MachineOperand.h
@@ -56,6 +56,7 @@ public:
MO_GlobalAddress, ///< Address of a global value
MO_BlockAddress, ///< Address of a basic block
MO_RegisterMask, ///< Mask of preserved registers.
+ MO_RegisterLiveOut, ///< Mask of live-out registers.
MO_Metadata, ///< Metadata reference (for debug info)
MO_MCSymbol ///< MCSymbol reference (for debug/eh info)
};
@@ -153,7 +154,7 @@ private:
const ConstantFP *CFP; // For MO_FPImmediate.
const ConstantInt *CI; // For MO_CImmediate. Integers > 64bit.
int64_t ImmVal; // For MO_Immediate.
- const uint32_t *RegMask; // For MO_RegisterMask.
+ const uint32_t *RegMask; // For MO_RegisterMask and MO_RegisterLiveOut.
const MDNode *MD; // For MO_Metadata.
MCSymbol *Sym; // For MO_MCSymbol
@@ -246,6 +247,8 @@ public:
bool isBlockAddress() const { return OpKind == MO_BlockAddress; }
/// isRegMask - Tests if this is a MO_RegisterMask operand.
bool isRegMask() const { return OpKind == MO_RegisterMask; }
+ /// isRegLiveOut - Tests if this is a MO_RegisterLiveOut operand.
+ bool isRegLiveOut() const { return OpKind == MO_RegisterLiveOut; }
/// isMetadata - Tests if this is a MO_Metadata operand.
bool isMetadata() const { return OpKind == MO_Metadata; }
bool isMCSymbol() const { return OpKind == MO_MCSymbol; }
@@ -476,6 +479,12 @@ public:
return Contents.RegMask;
}
+ /// getRegLiveOut - Returns a bit mask of live-out registers.
+ const uint32_t *getRegLiveOut() const {
+ assert(isRegLiveOut() && "Wrong MachineOperand accessor");
+ return Contents.RegMask;
+ }
+
const MDNode *getMetadata() const {
assert(isMetadata() && "Wrong MachineOperand accessor");
return Contents.MD;
@@ -659,6 +668,12 @@ public:
Op.Contents.RegMask = Mask;
return Op;
}
+ static MachineOperand CreateRegLiveOut(const uint32_t *Mask) {
+ assert(Mask && "Missing live-out register mask");
+ MachineOperand Op(MachineOperand::MO_RegisterLiveOut);
+ Op.Contents.RegMask = Mask;
+ return Op;
+ }
static MachineOperand CreateMetadata(const MDNode *Meta) {
MachineOperand Op(MachineOperand::MO_Metadata);
Op.Contents.MD = Meta;
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index ae4a2fa0bf..3fbc081ea3 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -568,6 +568,11 @@ namespace llvm {
/// bundles (created earlier, e.g. during pre-RA scheduling).
extern char &FinalizeMachineBundlesID;
+ /// StackMapLiveness - This pass analyses the register live-out set of
+ /// stackmap/patchpoint intrinsics and attaches the calculated information to
+ /// the intrinsic for later emission to the StackMap.
+ extern char &StackMapLivenessID;
+
} // End llvm namespace
#endif
diff --git a/include/llvm/CodeGen/StackMapLivenessAnalysis.h b/include/llvm/CodeGen/StackMapLivenessAnalysis.h
new file mode 100644
index 0000000000..4631f0fa79
--- /dev/null
+++ b/include/llvm/CodeGen/StackMapLivenessAnalysis.h
@@ -0,0 +1,67 @@
+//===--- StackMapLivenessAnalysis - StackMap Liveness Analysis --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass calculates the liveness for each basic block in a function and
+// attaches the register live-out information to a stackmap or patchpoint
+// intrinsic if present.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_STACKMAP_LIVENESS_ANALYSIS_H
+#define LLVM_CODEGEN_STACKMAP_LIVENESS_ANALYSIS_H
+
+#include "llvm/CodeGen/LivePhysRegs.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+
+
+namespace llvm {
+
+/// \brief This pass calculates the liveness information for each basic block in
+/// a function and attaches the register live-out information to a stackmap or
+/// patchpoint intrinsic if present.
+///
+/// This is an optional pass that has to be explicitely enabled via the
+/// -enable-stackmap-liveness flag. The pass skips functions that don't have any
+/// stackmap or patchpoint intrinsics. The information provided by this pass is
+/// optional and not required by the aformentioned intrinsics to function.
+class StackMapLiveness : public MachineFunctionPass {
+ MachineFunction *MF;
+ const TargetRegisterInfo *TRI;
+ LivePhysRegs LiveRegs;
+public:
+ static char ID;
+
+ /// \brief Default construct and initialize the pass.
+ StackMapLiveness();
+
+ /// \brief Tell the pass manager which passes we depend on and what
+ /// information we preserve.
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+ /// \brief Calculate the liveness information for the given machine function.
+ virtual bool runOnMachineFunction(MachineFunction &MF);
+
+private:
+ /// \brief Performs the actual liveness calculation for the function.
+ bool calculateLiveness();
+
+ /// \brief Add the current register live set to the instruction.
+ void addLiveOutSetToMI(MachineInstr &MI);
+
+ /// \brief Create a register mask and initialize it with the registers from
+ /// the register live set.
+ uint32_t *createRegisterMask() const;
+
+ /// \brief Print the current register live set for debugging.
+ void printLiveOutSet(raw_ostream &OS) const;
+};
+
+} // end llvm namespace
+
+#endif // end LLVM_CODEGEN_STACKMAP_LIVENESS_ANALYSIS_H
diff --git a/include/llvm/CodeGen/StackMaps.h b/include/llvm/CodeGen/StackMaps.h
index ef4657b139..19bc36e4dc 100644
--- a/include/llvm/CodeGen/StackMaps.h
+++ b/include/llvm/CodeGen/StackMaps.h
@@ -92,6 +92,20 @@ public:
: LocType(LocType), Size(Size), Reg(Reg), Offset(Offset) {}
};
+ struct LiveOutReg {
+ unsigned short Reg;
+ unsigned short RegNo;
+ unsigned short Size;
+
+ LiveOutReg() : Reg(0), RegNo(0), Size(0) {}
+ LiveOutReg(unsigned short Reg, unsigned short RegNo, unsigned short Size)
+ : Reg(Reg), RegNo(RegNo), Size(Size) {}
+
+ // Only sort by the dwarf register number.
+ bool operator< (const LiveOutReg &LO) const { return RegNo < LO.RegNo; }
+ static bool isInvalid(const LiveOutReg &LO) { return LO.Reg == 0; }
+ };
+
// OpTypes are used to encode information about the following logical
// operand (which may consist of several MachineOperands) for the
// OpParser.
@@ -114,15 +128,18 @@ public:
private:
typedef SmallVector<Location, 8> LocationVec;
+ typedef SmallVector<LiveOutReg, 8> LiveOutVec;
struct CallsiteInfo {
const MCExpr *CSOffsetExpr;
unsigned ID;
LocationVec Locations;
+ LiveOutVec LiveOuts;
CallsiteInfo() : CSOffsetExpr(0), ID(0) {}
CallsiteInfo(const MCExpr *CSOffsetExpr, unsigned ID,
- LocationVec Locations)
- : CSOffsetExpr(CSOffsetExpr), ID(ID), Locations(Locations) {}
+ LocationVec &Locations, LiveOutVec &LiveOuts)
+ : CSOffsetExpr(CSOffsetExpr), ID(ID), Locations(Locations),
+ LiveOuts(LiveOuts) {}
};
typedef std::vector<CallsiteInfo> CallsiteInfoList;
@@ -154,8 +171,15 @@ private:
/// Parse
std::pair<Location, MachineInstr::const_mop_iterator>
parseOperand(MachineInstr::const_mop_iterator MOI,
- MachineInstr::const_mop_iterator MOE);
-
+ MachineInstr::const_mop_iterator MOE) const;
+
+ /// \brief Create a live-out register record for the given register @p Reg.
+ LiveOutReg createLiveOutReg(unsigned Reg, const MCRegisterInfo &MCRI,
+ const TargetRegisterInfo *TRI) const;
+
+ /// \brief Parse the register live-out mask and return a vector of live-out
+ /// registers that need to be recorded in the stackmap.
+ LiveOutVec parseRegisterLiveOutMask(const uint32_t *Mask) const;
/// This should be called by the MC lowering code _immediately_ before
/// lowering the MI to an MCInst. It records where the operands for the