diff options
author | Dale Johannesen <dalej@apple.com> | 2008-09-17 21:13:11 +0000 |
---|---|---|
committer | Dale Johannesen <dalej@apple.com> | 2008-09-17 21:13:11 +0000 |
commit | 91aac1015e6714d959801dd8d60f55a72827dc4d (patch) | |
tree | c8440b8031a0fe3d7c63fcf9145ffc930759c547 /include/llvm | |
parent | 870e4bef419b1bd3e5ee05673975f1c05198b612 (diff) | |
download | llvm-91aac1015e6714d959801dd8d60f55a72827dc4d.tar.gz llvm-91aac1015e6714d959801dd8d60f55a72827dc4d.tar.bz2 llvm-91aac1015e6714d959801dd8d60f55a72827dc4d.tar.xz |
Add a bit to mark operands of asm's that conflict
with an earlyclobber operand elsewhere. Propagate
this bit and the earlyclobber bit through SDISel.
Change linear-scan RA not to allocate regs in a way
that conflicts with an earlyclobber. See also comments.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@56290 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm')
-rw-r--r-- | include/llvm/CodeGen/LiveIntervalAnalysis.h | 22 | ||||
-rw-r--r-- | include/llvm/CodeGen/MachineOperand.h | 21 | ||||
-rw-r--r-- | include/llvm/CodeGen/ScheduleDAG.h | 3 |
3 files changed, 44 insertions, 2 deletions
diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index c77513ca98..31eadcf7f8 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -28,6 +28,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Allocator.h" #include <cmath> +#include <map> namespace llvm { @@ -64,6 +65,22 @@ namespace llvm { AliasAnalysis *aa_; LiveVariables* lv_; + /// AsmsWithEarlyClobber - maps a virtual register number to all the + /// inline asm's that have the register marked earlyclobber. + /// + std::multimap<unsigned, MachineInstr*> AsmsThatEarlyClobber; + + /// AsmsWithEarlyClobberConflict - maps a virtual register number + /// to all the inline asm's that have earlyclobber operands elsewhere + /// and use the register as a (non-earlyclobber) input. + /// + /// Note: earlyclobber operands may not be assigned the same register as + /// each other, or as earlyclobber-conflict operands. However two + /// earlyclobber-conflict operands may be assigned the same register if + /// they happen to contain the same value. + /// + std::multimap<unsigned, MachineInstr*> AsmsWithEarlyClobberConflict; + /// Special pool allocator for VNInfo's (LiveInterval val#). /// BumpPtrAllocator VNInfoAllocator; @@ -336,6 +353,11 @@ namespace llvm { unsigned getNumConflictsWithPhysReg(const LiveInterval &li, unsigned PhysReg) const; + /// noEarlyclobberConflict - see whether virtual reg VReg has a conflict + /// with hard reg HReg because HReg is used as an earlyclobber register in + /// asm that also has VReg live into or across it. + bool noEarlyclobberConflict(unsigned VReg, VirtRegMap &vrm, unsigned HReg); + /// computeNumbering - Compute the index numbering. void computeNumbering(); diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index b0f7cc69f9..555f320027 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -73,6 +73,12 @@ private: /// for description of earlyclobber. bool IsEarlyClobber : 1; + /// OverlapsEarlyClobber - True if this MO_Register operand is used as an + /// input to an inline asm that has the earlyclobber bit set on some other + /// operand. Flag is not valid for any other case. See gcc doc + /// for description of earlyclobber. + bool OverlapsEarlyClobber : 1; + /// SubReg - Subregister number, only valid for MO_Register. A value of 0 /// indicates the MO_Register has no subReg. unsigned char SubReg; @@ -182,6 +188,11 @@ public: return IsEarlyClobber; } + bool overlapsEarlyClobber() const { + assert(isRegister() && "Wrong MachineOperand accessor"); + return OverlapsEarlyClobber; + } + /// getNextOperandForReg - Return the next MachineOperand in the function that /// uses or defines this register. MachineOperand *getNextOperandForReg() const { @@ -232,6 +243,11 @@ public: IsEarlyClobber = Val; } + void setOverlapsEarlyClobber(bool Val = true) { + assert(isRegister() && "Wrong MachineOperand accessor"); + OverlapsEarlyClobber = Val; + } + //===--------------------------------------------------------------------===// // Accessors for various operand types. //===--------------------------------------------------------------------===// @@ -337,13 +353,15 @@ public: static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp = false, bool isKill = false, bool isDead = false, unsigned SubReg = 0, - bool isEarlyClobber = false) { + bool isEarlyClobber = false, + bool overlapsEarlyClobber = false) { MachineOperand Op(MachineOperand::MO_Register); Op.IsDef = isDef; Op.IsImp = isImp; Op.IsKill = isKill; Op.IsDead = isDead; Op.IsEarlyClobber = isEarlyClobber; + Op.OverlapsEarlyClobber = overlapsEarlyClobber; Op.Contents.Reg.RegNo = Reg; Op.Contents.Reg.Prev = 0; Op.Contents.Reg.Next = 0; @@ -390,6 +408,7 @@ public: IsKill = MO.IsKill; IsDead = MO.IsDead; IsEarlyClobber = MO.IsEarlyClobber; + OverlapsEarlyClobber = MO.OverlapsEarlyClobber; SubReg = MO.SubReg; ParentMI = MO.ParentMI; Contents = MO.Contents; diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index 67f3dbb69f..01218ac997 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -361,7 +361,8 @@ namespace llvm { void AddOperand(MachineInstr *MI, SDValue Op, unsigned IIOpNum, const TargetInstrDesc *II, - DenseMap<SDValue, unsigned> &VRBaseMap); + DenseMap<SDValue, unsigned> &VRBaseMap, + bool overlapsEarlyClobber = false); void AddMemOperand(MachineInstr *MI, const MachineMemOperand &MO); |