summaryrefslogtreecommitdiff
path: root/include/llvm
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2008-09-17 21:13:11 +0000
committerDale Johannesen <dalej@apple.com>2008-09-17 21:13:11 +0000
commit91aac1015e6714d959801dd8d60f55a72827dc4d (patch)
treec8440b8031a0fe3d7c63fcf9145ffc930759c547 /include/llvm
parent870e4bef419b1bd3e5ee05673975f1c05198b612 (diff)
downloadllvm-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.h22
-rw-r--r--include/llvm/CodeGen/MachineOperand.h21
-rw-r--r--include/llvm/CodeGen/ScheduleDAG.h3
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);