summaryrefslogtreecommitdiff
path: root/include/llvm/CodeGen/FunctionLoweringInfo.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/CodeGen/FunctionLoweringInfo.h')
-rw-r--r--include/llvm/CodeGen/FunctionLoweringInfo.h72
1 files changed, 62 insertions, 10 deletions
diff --git a/include/llvm/CodeGen/FunctionLoweringInfo.h b/include/llvm/CodeGen/FunctionLoweringInfo.h
index 09a9991912daa..010e34179efc1 100644
--- a/include/llvm/CodeGen/FunctionLoweringInfo.h
+++ b/include/llvm/CodeGen/FunctionLoweringInfo.h
@@ -72,6 +72,37 @@ public:
/// MBBMap - A mapping from LLVM basic blocks to their machine code entry.
DenseMap<const BasicBlock*, MachineBasicBlock *> MBBMap;
+ typedef SmallVector<unsigned, 1> SwiftErrorVRegs;
+ typedef SmallVector<const Value*, 1> SwiftErrorValues;
+ /// A function can only have a single swifterror argument. And if it does
+ /// have a swifterror argument, it must be the first entry in
+ /// SwiftErrorVals.
+ SwiftErrorValues SwiftErrorVals;
+
+ /// Track the virtual register for each swifterror value in a given basic
+ /// block. Entries in SwiftErrorVRegs have the same ordering as entries
+ /// in SwiftErrorVals.
+ /// Note that another choice that is more straight-forward is to use
+ /// Map<const MachineBasicBlock*, Map<Value*, unsigned/*VReg*/>>. It
+ /// maintains a map from swifterror values to virtual registers for each
+ /// machine basic block. This choice does not require a one-to-one
+ /// correspondence between SwiftErrorValues and SwiftErrorVRegs. But because
+ /// of efficiency concern, we do not choose it.
+ llvm::DenseMap<const MachineBasicBlock*, SwiftErrorVRegs> SwiftErrorMap;
+
+ /// Track the virtual register for each swifterror value at the end of a basic
+ /// block when we need the assignment of a virtual register before the basic
+ /// block is visited. When we actually visit the basic block, we will make
+ /// sure the swifterror value is in the correct virtual register.
+ llvm::DenseMap<const MachineBasicBlock*, SwiftErrorVRegs>
+ SwiftErrorWorklist;
+
+ /// Find the swifterror virtual register in SwiftErrorMap. We will assert
+ /// failure when the value does not exist in swifterror map.
+ unsigned findSwiftErrorVReg(const MachineBasicBlock*, const Value*) const;
+ /// Set the swifterror virtual register in SwiftErrorMap.
+ void setSwiftErrorVReg(const MachineBasicBlock *MBB, const Value*, unsigned);
+
/// ValueMap - Since we emit code for the function a basic block at a time,
/// we must remember which virtual registers hold the values for
/// cross-basic-block values.
@@ -80,15 +111,36 @@ public:
/// Track virtual registers created for exception pointers.
DenseMap<const Value *, unsigned> CatchPadExceptionPointers;
- // Keep track of frame indices allocated for statepoints as they could be used
- // across basic block boundaries.
- // Key of the map is statepoint instruction, value is a map from spilled
- // llvm Value to the optional stack stack slot index.
- // If optional is unspecified it means that we have visited this value
- // but didn't spill it.
- typedef DenseMap<const Value*, Optional<int>> StatepointSpilledValueMapTy;
- DenseMap<const Instruction*, StatepointSpilledValueMapTy>
- StatepointRelocatedValues;
+ /// Keep track of frame indices allocated for statepoints as they could be
+ /// used across basic block boundaries. This struct is more complex than a
+ /// simple map because the stateopint lowering code de-duplicates gc pointers
+ /// based on their SDValue (so %p and (bitcast %p to T) will get the same
+ /// slot), and we track that here.
+
+ struct StatepointSpillMap {
+ typedef DenseMap<const Value *, Optional<int>> SlotMapTy;
+
+ /// Maps uniqued llvm IR values to the slots they were spilled in. If a
+ /// value is mapped to None it means we visited the value but didn't spill
+ /// it (because it was a constant, for instance).
+ SlotMapTy SlotMap;
+
+ /// Maps llvm IR values to the values they were de-duplicated to.
+ DenseMap<const Value *, const Value *> DuplicateMap;
+
+ SlotMapTy::const_iterator find(const Value *V) const {
+ auto DuplIt = DuplicateMap.find(V);
+ if (DuplIt != DuplicateMap.end())
+ V = DuplIt->second;
+ return SlotMap.find(V);
+ }
+
+ SlotMapTy::const_iterator end() const { return SlotMap.end(); }
+ };
+
+ /// Maps gc.statepoint instructions to their corresponding StatepointSpillMap
+ /// instances.
+ DenseMap<const Instruction *, StatepointSpillMap> StatepointSpillMaps;
/// StaticAllocaMap - Keep track of frame indices for fixed sized allocas in
/// the entry block. This allows the allocas to be efficiently referenced
@@ -119,7 +171,7 @@ public:
struct LiveOutInfo {
unsigned NumSignBits : 31;
- bool IsValid : 1;
+ unsigned IsValid : 1;
APInt KnownOne, KnownZero;
LiveOutInfo() : NumSignBits(0), IsValid(true), KnownOne(1, 0),
KnownZero(1, 0) {}