[Mesa-dev] [PATCH 1/2] nv50/ir: create PhiInstruction as a sibling of Instruction
Rhys Perry
pendingchaos02 at gmail.com
Wed Jul 11 15:58:11 UTC 2018
Signed-off-by: Rhys Perry <pendingchaos02 at gmail.com>
---
src/gallium/drivers/nouveau/codegen/nv50_ir.cpp | 140 +++++++----
src/gallium/drivers/nouveau/codegen/nv50_ir.h | 184 ++++++++------
src/gallium/drivers/nouveau/codegen/nv50_ir_bb.cpp | 71 +++---
.../drivers/nouveau/codegen/nv50_ir_build_util.h | 12 +-
.../drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp | 24 +-
.../drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp | 24 +-
.../drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp | 10 +-
.../drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp | 16 +-
.../drivers/nouveau/codegen/nv50_ir_inlines.h | 55 ++++-
.../nouveau/codegen/nv50_ir_lowering_nv50.cpp | 24 +-
.../nouveau/codegen/nv50_ir_lowering_nvc0.cpp | 54 ++---
.../nouveau/codegen/nv50_ir_lowering_nvc0.h | 16 +-
.../drivers/nouveau/codegen/nv50_ir_peephole.cpp | 269 +++++++++++----------
.../drivers/nouveau/codegen/nv50_ir_print.cpp | 81 ++++---
src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp | 99 ++++----
.../drivers/nouveau/codegen/nv50_ir_ssa.cpp | 22 +-
.../drivers/nouveau/codegen/nv50_ir_target.cpp | 30 +--
src/gallium/drivers/nouveau/codegen/nv50_ir_util.h | 2 +
18 files changed, 652 insertions(+), 481 deletions(-)
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir.cpp
index 49425b98b9..d28022fce5 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir.cpp
@@ -98,7 +98,7 @@ bool ValueRef::getImmediate(ImmediateValue &imm) const
return true;
}
- Instruction *insn = src->value->getUniqueInsn();
+ BaseInstruction *insn = src->value->getUniqueInsn();
if (insn && insn->op == OP_MOV) {
src = &insn->src(0);
@@ -177,7 +177,7 @@ ValueDef::mayReplace(const ValueRef &rep)
for (Value::UseIterator it = value->uses.begin(); it != value->uses.end();
++it) {
- Instruction *insn = (*it)->getInsn();
+ BaseInstruction *insn = (*it)->getInsn();
int s = -1;
for (int i = 0; insn->srcExists(i); ++i) {
@@ -191,7 +191,7 @@ ValueDef::mayReplace(const ValueRef &rep)
}
assert(s >= 0); // integrity of uses list
- if (!target->isModSupported(insn, s, rep.mod))
+ if (asInsn(insn) && !target->isModSupported(asInsn(insn), s, rep.mod))
return false;
}
return true;
@@ -273,7 +273,7 @@ LValue::isUniform() const
{
if (defs.size() > 1)
return false;
- Instruction *insn = getInsn();
+ BaseInstruction *insn = getInsn();
// let's not try too hard here for now ...
return !insn->srcExists(1) && insn->getSrc(0)->isUniform();
}
@@ -558,23 +558,34 @@ Symbol::equals(const Value *that, bool strict) const
return this->reg.data.offset == that->reg.data.offset;
}
-void Instruction::init()
+BaseInstruction::BaseInstruction(Function *fn, operation opr, DataType ty)
+ : op(opr), dType(ty), sType(ty)
{
- next = prev = 0;
+ next = prev = NULL;
+ fixed = 0;
+ terminator = 0;
+ join = 0;
+
+ if (fn) {
+ fn->add(this, id);
+ } else {
+ id = -1;
+ bb = 0;
+ }
+}
+void Instruction::init()
+{
cc = CC_ALWAYS;
rnd = ROUND_N;
cache = CACHE_CA;
subOp = 0;
saturate = 0;
- join = 0;
exit = 0;
- terminator = 0;
ftz = 0;
dnz = 0;
perPatch = 0;
- fixed = 0;
encSize = 0;
ipa = 0;
mask = 0;
@@ -589,28 +600,19 @@ void Instruction::init()
flagsSrc = -1;
}
-Instruction::Instruction()
+Instruction::Instruction() : BaseInstruction(NULL, OP_NOP, TYPE_F32)
{
init();
-
- op = OP_NOP;
- dType = sType = TYPE_F32;
-
- id = -1;
- bb = 0;
}
Instruction::Instruction(Function *fn, operation opr, DataType ty)
+ : BaseInstruction(fn, opr, ty)
{
+ assert(opr != OP_PHI);
init();
-
- op = opr;
- dType = sType = ty;
-
- fn->add(this, id);
}
-Instruction::~Instruction()
+BaseInstruction::~BaseInstruction()
{
if (bb) {
Function *fn = bb->getFunction();
@@ -619,14 +621,14 @@ Instruction::~Instruction()
}
for (int s = 0; srcExists(s); ++s)
- setSrc(s, NULL);
+ srcs[s].set(NULL);
// must unlink defs too since the list pointers will get deallocated
for (int d = 0; defExists(d); ++d)
- setDef(d, NULL);
+ defs[d].set(NULL);
}
void
-Instruction::setDef(int i, Value *val)
+BaseInstruction::setDef(int i, Value *val)
{
int size = defs.size();
if (i >= size) {
@@ -740,18 +742,35 @@ Instruction::putExtraSources(int s, Value *values[3])
setPredicate(cc, values[2]);
}
+BaseInstruction *
+BaseInstruction::clone(ClonePolicy<Function>& pol, BaseInstruction *i) const
+{
+ assert(i);
+
+ pol.set<BaseInstruction>(this, i);
+
+ i->op = op;
+ i->dType = dType;
+ i->sType = sType;
+
+ for (int d = 0; defExists(d); ++d)
+ i->setDef(d, pol.get(getDef(d)));
+
+ return i;
+}
+
Instruction *
-Instruction::clone(ClonePolicy<Function>& pol, Instruction *i) const
+Instruction::clone(ClonePolicy<Function>& pol, BaseInstruction *bi) const
{
- if (!i)
- i = new_Instruction(pol.context(), op, dType);
+ if (!bi)
+ bi = new_Instruction(pol.context(), op, dType);
#ifndef NDEBUG // non-conformant assert, so this is required
- assert(typeid(*i) == typeid(*this));
+ assert(typeid(*bi) == typeid(*this));
#endif
- pol.set<Instruction>(this, i);
+ BaseInstruction::clone(pol, bi);
- i->sType = sType;
+ Instruction *i = static_cast<Instruction *>(bi);
i->rnd = rnd;
i->cache = cache;
@@ -769,9 +788,6 @@ Instruction::clone(ClonePolicy<Function>& pol, Instruction *i) const
i->postFactor = postFactor;
- for (int d = 0; defExists(d); ++d)
- i->setDef(d, pol.get(getDef(d)));
-
for (int s = 0; srcExists(s); ++s) {
i->setSrc(s, pol.get(getSrc(s)));
i->src(s).mod = src(s).mod;
@@ -786,7 +802,7 @@ Instruction::clone(ClonePolicy<Function>& pol, Instruction *i) const
}
unsigned int
-Instruction::defCount(unsigned int mask, bool singleFile) const
+BaseInstruction::defCount(unsigned int mask, bool singleFile) const
{
unsigned int i, n;
@@ -805,7 +821,7 @@ Instruction::defCount(unsigned int mask, bool singleFile) const
}
unsigned int
-Instruction::srcCount(unsigned int mask, bool singleFile) const
+BaseInstruction::srcCount(unsigned int mask, bool singleFile) const
{
unsigned int i, n;
@@ -926,7 +942,7 @@ TexInstruction::~TexInstruction()
}
TexInstruction *
-TexInstruction::clone(ClonePolicy<Function>& pol, Instruction *i) const
+TexInstruction::clone(ClonePolicy<Function>& pol, BaseInstruction *i) const
{
TexInstruction *tex = (i ? static_cast<TexInstruction *>(i) :
new_TexInstruction(pol.context(), op));
@@ -1051,7 +1067,7 @@ CmpInstruction::CmpInstruction(Function *fn, operation op)
}
CmpInstruction *
-CmpInstruction::clone(ClonePolicy<Function>& pol, Instruction *i) const
+CmpInstruction::clone(ClonePolicy<Function>& pol, BaseInstruction *i) const
{
CmpInstruction *cmp = (i ? static_cast<CmpInstruction *>(i) :
new_CmpInstruction(pol.context(), op));
@@ -1081,7 +1097,7 @@ FlowInstruction::FlowInstruction(Function *fn, operation op, void *targ)
}
FlowInstruction *
-FlowInstruction::clone(ClonePolicy<Function>& pol, Instruction *i) const
+FlowInstruction::clone(ClonePolicy<Function>& pol, BaseInstruction *i) const
{
FlowInstruction *flow = (i ? static_cast<FlowInstruction *>(i) :
new_FlowInstruction(pol.context(), op, NULL));
@@ -1104,6 +1120,42 @@ FlowInstruction::clone(ClonePolicy<Function>& pol, Instruction *i) const
return flow;
}
+PhiInstruction::PhiInstruction(Function *fn, DataType ty)
+ : BaseInstruction(fn, OP_PHI, ty) {}
+
+PhiInstruction *
+PhiInstruction::clone(ClonePolicy<Function>& pol, BaseInstruction *i) const
+{
+ assert(op == OP_PHI);
+
+ PhiInstruction *phi = (i ? static_cast<PhiInstruction *>(i) :
+ new_PhiInstruction(pol.context(), dType));
+
+ BaseInstruction::clone(pol, phi);
+
+ return phi;
+}
+
+void
+PhiInstruction::setSrc(int s, Value *val)
+{
+ int size = srcs.size();
+ if (s >= size) {
+ srcs.resize(s + 1);
+ while (size <= s)
+ srcs[size++].setInsn(this);
+ }
+
+ srcs[s].set(val);
+}
+
+void
+PhiInstruction::setSrc(int s, const ValueRef& ref)
+{
+ setSrc(s, ref.get());
+ srcs[s].mod = ref.mod;
+}
+
Program::Program(Type type, Target *arch)
: progType(type),
target(arch),
@@ -1111,6 +1163,7 @@ Program::Program(Type type, Target *arch)
mem_CmpInstruction(sizeof(CmpInstruction), 4),
mem_TexInstruction(sizeof(TexInstruction), 4),
mem_FlowInstruction(sizeof(FlowInstruction), 4),
+ mem_PhiInstruction(sizeof(PhiInstruction), 4),
mem_LValue(sizeof(LValue), 8),
mem_Symbol(sizeof(Symbol), 7),
mem_ImmediateValue(sizeof(ImmediateValue), 7)
@@ -1138,11 +1191,11 @@ Program::~Program()
releaseValue(reinterpret_cast<Value *>(it.get()));
}
-void Program::releaseInstruction(Instruction *insn)
+void Program::releaseInstruction(BaseInstruction *insn)
{
// TODO: make this not suck so much
- insn->~Instruction();
+ insn->~BaseInstruction();
if (insn->asCmp())
mem_CmpInstruction.release(insn);
@@ -1153,7 +1206,12 @@ void Program::releaseInstruction(Instruction *insn)
if (insn->asFlow())
mem_FlowInstruction.release(insn);
else
+ if (asPhi(insn))
+ mem_PhiInstruction.release(insn);
+ else if (asInsn(insn))
mem_Instruction.release(insn);
+ else
+ assert(false);
}
void Program::releaseValue(Value *value)
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir.h b/src/gallium/drivers/nouveau/codegen/nv50_ir.h
index f4f3c70888..b80397a0b9 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir.h
@@ -485,6 +485,8 @@ class BasicBlock;
class Target;
+class BaseInstruction;
+class PhiInstruction;
class Instruction;
class CmpInstruction;
class TexInstruction;
@@ -539,6 +541,11 @@ struct Storage
#define NV50_IR_INTERP_OFFSET (2 << 2)
#define NV50_IR_INTERP_SAMPLEID (3 << 2)
+static inline PhiInstruction *asPhi(BaseInstruction *i);
+static inline const PhiInstruction *asPhi(const BaseInstruction *i);
+static inline Instruction *asInsn(BaseInstruction *i);
+static inline const Instruction *asInsn(const BaseInstruction *i);
+
// do we really want this to be a class ?
class Modifier
{
@@ -586,8 +593,8 @@ public:
inline Value *get() const { return value; }
inline Value *rep() const;
- inline Instruction *getInsn() const { return insn; }
- inline void setInsn(Instruction *inst) { insn = inst; }
+ inline BaseInstruction *getInsn() const { return insn; }
+ inline void setInsn(BaseInstruction *inst) { insn = inst; }
inline bool isIndirect(int dim) const { return indirect[dim] >= 0; }
inline const ValueRef *getIndirect(int dim) const;
@@ -606,7 +613,7 @@ public:
private:
Value *value;
- Instruction *insn;
+ BaseInstruction *insn;
};
class ValueDef
@@ -624,8 +631,8 @@ public:
bool mayReplace(const ValueRef &);
void replace(const ValueRef &, bool doSet); // replace all uses of the old value
- inline Instruction *getInsn() const { return insn; }
- inline void setInsn(Instruction *inst) { insn = inst; }
+ inline BaseInstruction *getInsn() const { return insn; }
+ inline void setInsn(BaseInstruction *inst) { insn = inst; }
inline DataFile getFile() const;
inline unsigned getSize() const;
@@ -636,7 +643,7 @@ public:
private:
Value *value; // should make this LValue * ...
LValue *origin; // pre SSA value
- Instruction *insn;
+ BaseInstruction *insn;
};
class Value
@@ -655,8 +662,8 @@ public:
inline Value *rep() const { return join; }
- inline Instruction *getUniqueInsn() const;
- inline Instruction *getInsn() const; // use when uniqueness is certain
+ inline BaseInstruction *getUniqueInsn() const;
+ inline BaseInstruction *getInsn() const; // use when uniqueness is certain
inline int refCount() { return uses.size(); }
@@ -774,26 +781,18 @@ public:
virtual int print(char *, size_t, DataType ty = TYPE_NONE) const;
};
-class Instruction
+class BaseInstruction
{
public:
- Instruction();
- Instruction(Function *, operation, DataType);
- virtual ~Instruction();
+ virtual ~BaseInstruction();
- virtual Instruction *clone(ClonePolicy<Function>&,
- Instruction * = NULL) const;
+ virtual BaseInstruction *clone(ClonePolicy<Function>&,
+ BaseInstruction * = NULL) const;
void setDef(int i, Value *);
- void setSrc(int s, Value *);
- void setSrc(int s, const ValueRef&);
- void swapSources(int a, int b);
- void moveSources(int s, int delta);
- bool setIndirect(int s, int dim, Value *);
- inline ValueRef& src(int s) { return srcs[s]; }
- inline ValueDef& def(int s) { return defs[s]; }
inline const ValueRef& src(int s) const { return srcs[s]; }
+ inline ValueDef& def(int s) { return defs[s]; }
inline const ValueDef& def(int s) const { return defs[s]; }
inline Value *getDef(int d) const { return defs[d].get(); }
@@ -811,24 +810,11 @@ public:
inline bool constrainedDefs() const;
- bool setPredicate(CondCode ccode, Value *);
- inline Value *getPredicate() const;
- bool writesPredicate() const;
- inline bool isPredicated() const { return predSrc >= 0; }
-
- inline void setFlagsSrc(int s, Value *);
- inline void setFlagsDef(int d, Value *);
- inline bool usesFlags() const { return flagsSrc >= 0; }
-
unsigned int defCount() const { return defs.size(); };
unsigned int defCount(unsigned int mask, bool singleFile = false) const;
unsigned int srcCount() const { return srcs.size(); };
unsigned int srcCount(unsigned int mask, bool singleFile = false) const;
- // save & remove / set indirect[0,1] and predicate source
- void takeExtraSources(int s, Value *[3]);
- void putExtraSources(int s, Value *[3]);
-
inline void setType(DataType type) { dType = sType = type; }
inline void setType(DataType dtype, DataType stype)
@@ -840,13 +826,8 @@ public:
inline bool isPseudo() const { return op < OP_MOV; }
bool isDead() const;
bool isNop() const;
- bool isCommutationLegal(const Instruction *) const; // must be adjacent !
- bool isActionEqual(const Instruction *) const;
- bool isResultEqual(const Instruction *) const;
-
- // check whether the defs interfere with srcs and defs of another instruction
- bool canCommuteDefDef(const Instruction *) const;
- bool canCommuteDefSrc(const Instruction *) const;
+ bool isActionEqual(const BaseInstruction *) const;
+ bool isResultEqual(const BaseInstruction *) const;
void print() const;
@@ -858,14 +839,88 @@ public:
inline const FlowInstruction *asFlow() const;
public:
- Instruction *next;
- Instruction *prev;
+ BaseInstruction *next;
+ BaseInstruction *prev;
int id;
int serial; // CFG order
operation op;
DataType dType; // destination or defining type
DataType sType; // source or secondary type
+
+ unsigned fixed : 1; // prevent dead code elimination
+ unsigned terminator : 1; // end of basic block
+ unsigned join : 1; // converge control flow (use OP_JOIN until end)
+
+ BasicBlock *bb;
+
+protected:
+ BaseInstruction();
+ BaseInstruction(Function *, operation, DataType);
+
+ std::deque<ValueDef> defs; // no gaps !
+ std::deque<ValueRef> srcs; // no gaps !
+};
+
+class PhiInstruction : public BaseInstruction
+{
+public:
+ PhiInstruction(Function *, DataType);
+
+ virtual PhiInstruction *clone(ClonePolicy<Function>&,
+ BaseInstruction * = NULL) const;
+
+ void setSrc(int s, Value *);
+ void setSrc(int s, const ValueRef&);
+};
+
+class Instruction : public BaseInstruction
+{
+public:
+ Instruction();
+ Instruction(Function *, operation, DataType);
+
+ virtual Instruction *clone(ClonePolicy<Function>&,
+ BaseInstruction * = NULL) const;
+
+ void setSrc(int s, Value *);
+ void setSrc(int s, const ValueRef&);
+ void swapSources(int a, int b);
+ void moveSources(int s, int delta);
+ bool setIndirect(int s, int dim, Value *);
+
+ inline const ValueRef& src(int s) const { return srcs[s]; }
+ inline ValueRef& src(int s) { return srcs[s]; }
+
+ bool setPredicate(CondCode ccode, Value *);
+ inline Value *getPredicate() const;
+ bool writesPredicate() const;
+ inline bool isPredicated() const { return predSrc >= 0; }
+
+ inline void setFlagsSrc(int s, Value *);
+ inline void setFlagsDef(int d, Value *);
+ inline bool usesFlags() const { return flagsSrc >= 0; }
+
+ // save & remove / set indirect[0,1] and predicate source
+ void takeExtraSources(int s, Value *[3]);
+ void putExtraSources(int s, Value *[3]);
+
+ bool isCommutationLegal(const Instruction *) const; // must be adjacent !
+
+ // check whether the defs interfere with srcs and defs of another instruction
+ bool canCommuteDefDef(const Instruction *) const;
+ bool canCommuteDefSrc(const Instruction *) const;
+
+ inline Instruction *getPrev() const {
+ return asInsn(prev);
+ }
+
+ inline Instruction *getNext() const {
+ assert(next ? asInsn(next) != NULL : true);
+ return static_cast<Instruction *>(next);
+ }
+
+public:
CondCode cc;
RoundMode rnd;
CacheMode cache;
@@ -874,9 +929,6 @@ public:
unsigned encSize : 4; // encoding size in bytes
unsigned saturate : 1; // to [0.0f, 1.0f]
- unsigned join : 1; // converge control flow (use OP_JOIN until end)
- unsigned fixed : 1; // prevent dead code elimination
- unsigned terminator : 1; // end of basic block
unsigned ftz : 1; // flush denormal to zero
unsigned dnz : 1; // denormals, NaN are zero
unsigned ipa : 4; // interpolation mode
@@ -895,12 +947,6 @@ public:
uint32_t sched; // scheduling data (NOTE: maybe move to separate storage)
- BasicBlock *bb;
-
-protected:
- std::deque<ValueDef> defs; // no gaps !
- std::deque<ValueRef> srcs; // no gaps !
-
// instruction specific methods:
// (don't want to subclass, would need more constructors and memory pools)
public:
@@ -995,7 +1041,7 @@ public:
virtual ~TexInstruction();
virtual TexInstruction *clone(ClonePolicy<Function>&,
- Instruction * = NULL) const;
+ BaseInstruction * = NULL) const;
inline void setTexture(Target targ, uint8_t r, uint8_t s)
{
@@ -1044,7 +1090,7 @@ public:
CmpInstruction(Function *, operation);
virtual CmpInstruction *clone(ClonePolicy<Function>&,
- Instruction * = NULL) const;
+ BaseInstruction * = NULL) const;
void setCondition(CondCode cond) { setCond = cond; }
CondCode getCondition() const { return setCond; }
@@ -1059,7 +1105,7 @@ public:
FlowInstruction(Function *, operation, void *target);
virtual FlowInstruction *clone(ClonePolicy<Function>&,
- Instruction * = NULL) const;
+ BaseInstruction * = NULL) const;
public:
unsigned allWarp : 1;
@@ -1099,16 +1145,16 @@ public:
Program *getProgram() const { return program; }
Instruction *getEntry() const { return entry; } // first non-phi instruction
- Instruction *getPhi() const { return phi; }
- Instruction *getFirst() const { return phi ? phi : entry; }
- Instruction *getExit() const { return exit; }
+ PhiInstruction *getPhi() const { return phi; }
+ BaseInstruction *getFirst() const { return phi ? static_cast<BaseInstruction *>(phi) : static_cast<BaseInstruction *>(entry); }
+ BaseInstruction *getExit() const { return exit; }
- void insertHead(Instruction *);
- void insertTail(Instruction *);
- void insertBefore(Instruction *, Instruction *);
- void insertAfter(Instruction *, Instruction *);
- void remove(Instruction *);
- void permuteAdjacent(Instruction *, Instruction *);
+ void insertHead(BaseInstruction *);
+ void insertTail(BaseInstruction *);
+ void insertBefore(BaseInstruction *, BaseInstruction *);
+ void insertAfter(BaseInstruction *, BaseInstruction *);
+ void remove(BaseInstruction *);
+ void permuteAdjacent(BaseInstruction *, BaseInstruction *);
BasicBlock *idom() const;
@@ -1140,9 +1186,9 @@ private:
int id;
DLList df;
- Instruction *phi;
+ PhiInstruction *phi;
Instruction *entry;
- Instruction *exit;
+ BaseInstruction *exit;
unsigned int numInsns;
@@ -1176,7 +1222,7 @@ public:
unsigned int orderInstructions(ArrayList&);
inline void add(BasicBlock *bb, int& id) { allBBlocks.insert(bb, id); }
- inline void add(Instruction *insn, int& id) { allInsns.insert(insn, id); }
+ inline void add(BaseInstruction *insn, int& id) { allInsns.insert(insn, id); }
inline void add(LValue *lval, int& id) { allLValues.insert(lval, id); }
inline LValue *getLValue(int id);
@@ -1287,6 +1333,7 @@ public:
MemoryPool mem_CmpInstruction;
MemoryPool mem_TexInstruction;
MemoryPool mem_FlowInstruction;
+ MemoryPool mem_PhiInstruction;
MemoryPool mem_LValue;
MemoryPool mem_Symbol;
MemoryPool mem_ImmediateValue;
@@ -1298,7 +1345,7 @@ public:
const struct nv50_ir_prog_info *driver; // for driver configuration
- void releaseInstruction(Instruction *);
+ void releaseInstruction(BaseInstruction *);
void releaseValue(Value *);
};
@@ -1313,6 +1360,7 @@ private:
// return false to continue with next entity on next higher level
virtual bool visit(Function *) { return true; }
virtual bool visit(BasicBlock *) { return true; }
+ virtual bool visit(BaseInstruction *i);
virtual bool visit(Instruction *) { return false; }
bool doRun(Program *, bool ordered, bool skipPhi);
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_bb.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_bb.cpp
index 9f0e073332..b3d4d8b856 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_bb.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_bb.cpp
@@ -62,7 +62,7 @@ Function::~Function()
outs.clear();
for (ArrayList::Iterator it = allInsns.iterator(); !it.end(); it.next())
- delete_Instruction(prog, reinterpret_cast<Instruction *>(it.get()));
+ delete_Instruction(prog, reinterpret_cast<BaseInstruction *>(it.get()));
for (ArrayList::Iterator it = allLValues.iterator(); !it.end(); it.next())
delete_Value(prog, reinterpret_cast<LValue *>(it.get()));
@@ -75,7 +75,9 @@ BasicBlock::BasicBlock(Function *fn) : cfg(this), dom(this), func(fn)
{
program = func->getProgram();
- joinAt = phi = entry = exit = NULL;
+ joinAt = entry = NULL;
+ exit = NULL;
+ phi = NULL;
numInsns = 0;
binPos = 0;
@@ -98,7 +100,7 @@ BasicBlock::clone(ClonePolicy<Function>& pol) const
pol.set(this, bb);
- for (Instruction *i = getFirst(); i; i = i->next)
+ for (BaseInstruction *i = getFirst(); i; i = i->next)
bb->insertTail(i->clone(pol));
pol.context()->cfg.insert(&bb->cfg);
@@ -119,7 +121,7 @@ BasicBlock::idom() const
}
void
-BasicBlock::insertHead(Instruction *inst)
+BasicBlock::insertHead(BaseInstruction *inst)
{
assert(inst->next == 0 && inst->prev == 0);
@@ -131,7 +133,8 @@ BasicBlock::insertHead(Instruction *inst)
insertBefore(entry, inst);
} else {
assert(!exit);
- phi = exit = inst;
+ phi = asPhi(inst);
+ exit = inst;
inst->bb = this;
++numInsns;
}
@@ -144,7 +147,8 @@ BasicBlock::insertHead(Instruction *inst)
insertAfter(exit, inst); // after last phi
} else {
assert(!exit);
- entry = exit = inst;
+ entry = asInsn(inst);
+ exit = inst;
inst->bb = this;
++numInsns;
}
@@ -153,7 +157,7 @@ BasicBlock::insertHead(Instruction *inst)
}
void
-BasicBlock::insertTail(Instruction *inst)
+BasicBlock::insertTail(BaseInstruction *inst)
{
assert(inst->next == 0 && inst->prev == 0);
@@ -166,7 +170,8 @@ BasicBlock::insertTail(Instruction *inst)
insertAfter(exit, inst);
} else {
assert(!phi);
- phi = exit = inst;
+ phi = asPhi(inst);
+ exit = inst;
inst->bb = this;
++numInsns;
}
@@ -175,7 +180,8 @@ BasicBlock::insertTail(Instruction *inst)
insertAfter(exit, inst);
} else {
assert(!phi);
- entry = exit = inst;
+ entry = asInsn(inst);
+ exit = inst;
inst->bb = this;
++numInsns;
}
@@ -183,7 +189,7 @@ BasicBlock::insertTail(Instruction *inst)
}
void
-BasicBlock::insertBefore(Instruction *q, Instruction *p)
+BasicBlock::insertBefore(BaseInstruction *q, BaseInstruction *p)
{
assert(p && q);
@@ -192,14 +198,14 @@ BasicBlock::insertBefore(Instruction *q, Instruction *p)
if (q == entry) {
if (p->op == OP_PHI) {
if (!phi)
- phi = p;
+ phi = asPhi(p);
} else {
- entry = p;
+ entry = asInsn(p);
}
} else
if (q == phi) {
assert(p->op == OP_PHI);
- phi = p;
+ phi = asPhi(p);
}
p->next = q;
@@ -213,7 +219,7 @@ BasicBlock::insertBefore(Instruction *q, Instruction *p)
}
void
-BasicBlock::insertAfter(Instruction *p, Instruction *q)
+BasicBlock::insertAfter(BaseInstruction *p, BaseInstruction *q)
{
assert(p && q);
assert(q->op != OP_PHI || p->op == OP_PHI);
@@ -223,7 +229,7 @@ BasicBlock::insertAfter(Instruction *p, Instruction *q)
if (p == exit)
exit = q;
if (p->op == OP_PHI && q->op != OP_PHI)
- entry = q;
+ entry = asInsn(q);
q->prev = p;
q->next = p->next;
@@ -236,7 +242,7 @@ BasicBlock::insertAfter(Instruction *p, Instruction *q)
}
void
-BasicBlock::remove(Instruction *insn)
+BasicBlock::remove(BaseInstruction *insn)
{
assert(insn->bb == this);
@@ -250,16 +256,16 @@ BasicBlock::remove(Instruction *insn)
if (insn == entry) {
if (insn->next)
- entry = insn->next;
+ entry = asInsn(insn->next);
else
if (insn->prev && insn->prev->op != OP_PHI)
- entry = insn->prev;
+ entry = asInsn(insn->prev);
else
entry = NULL;
}
if (insn == phi)
- phi = (insn->next && insn->next->op == OP_PHI) ? insn->next : 0;
+ phi = asPhi(insn->next);
--numInsns;
insn->bb = NULL;
@@ -267,12 +273,12 @@ BasicBlock::remove(Instruction *insn)
insn->prev = NULL;
}
-void BasicBlock::permuteAdjacent(Instruction *a, Instruction *b)
+void BasicBlock::permuteAdjacent(BaseInstruction *a, BaseInstruction *b)
{
assert(a->bb == b->bb);
if (a->next != b) {
- Instruction *i = a;
+ BaseInstruction *i = a;
a = b;
b = i;
}
@@ -282,7 +288,7 @@ void BasicBlock::permuteAdjacent(Instruction *a, Instruction *b)
if (b == exit)
exit = a;
if (a == entry)
- entry = b;
+ entry = asInsn(b);
b->prev = a->prev;
a->next = b->next;
@@ -316,7 +322,7 @@ BasicBlock::splitCommon(Instruction *insn, BasicBlock *bb, bool attach)
this->cfg.detach(e->getTarget());
}
- for (; insn; insn = insn->next) {
+ for (; insn; insn = insn->getNext()) {
this->numInsns--;
bb->numInsns++;
insn->bb = bb;
@@ -348,7 +354,7 @@ BasicBlock::splitAfter(Instruction *insn, bool attach)
bb->joinAt = joinAt;
joinAt = NULL;
- splitCommon(insn ? insn->next : NULL, bb, attach);
+ splitCommon(insn ? insn->getNext() : NULL, bb, attach);
return bb;
}
@@ -422,7 +428,7 @@ Function::orderInstructions(ArrayList &result)
BasicBlock *bb =
BasicBlock::get(reinterpret_cast<Graph::Node *>(it->get()));
- for (Instruction *insn = bb->getFirst(); insn; insn = insn->next)
+ for (BaseInstruction *insn = bb->getFirst(); insn; insn = insn->next)
result.insert(insn, insn->serial);
}
@@ -482,7 +488,7 @@ Pass::doRun(Function *func, bool ordered, bool skipPhi)
{
IteratorRef bbIter;
BasicBlock *bb;
- Instruction *insn, *next;
+ BaseInstruction *insn, *next;
this->func = func;
if (!visit(func))
@@ -494,8 +500,9 @@ Pass::doRun(Function *func, bool ordered, bool skipPhi)
bb = BasicBlock::get(reinterpret_cast<Graph::Node *>(bbIter->get()));
if (!visit(bb))
break;
- for (insn = skipPhi ? bb->getEntry() : bb->getFirst(); insn != NULL;
- insn = next) {
+ insn = skipPhi ? static_cast<BaseInstruction *>(bb->getEntry()) :
+ bb->getFirst();
+ for (; insn != NULL; insn = next) {
next = insn->next;
if (!visit(insn))
break;
@@ -505,6 +512,14 @@ Pass::doRun(Function *func, bool ordered, bool skipPhi)
return !err;
}
+bool Pass::visit(BaseInstruction *i)
+{
+ if (asInsn(i))
+ return visit(asInsn(i));
+ else
+ return true;
+}
+
void
Function::printCFGraph(const char *filePath)
{
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.h
index d171f64d9a..865b4afc98 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.h
@@ -38,12 +38,12 @@ public:
// keeps inserting at head/tail of block
inline void setPosition(BasicBlock *, bool tail);
// position advances only if @after is true
- inline void setPosition(Instruction *, bool after);
+ inline void setPosition(BaseInstruction *, bool after);
inline BasicBlock *getBB() { return bb; }
- inline void insert(Instruction *);
- inline void remove(Instruction *i) { assert(i->bb == bb); bb->remove(i); }
+ inline void insert(BaseInstruction *);
+ inline void remove(BaseInstruction *i) { assert(i->bb == bb); bb->remove(i); }
inline LValue *getScratch(int size = 4, DataFile = FILE_GPR);
// scratch value for a single assignment:
@@ -183,7 +183,7 @@ private:
protected:
Program *prog;
Function *func;
- Instruction *pos;
+ BaseInstruction *pos;
BasicBlock *bb;
bool tail;
@@ -214,7 +214,7 @@ BuildUtil::setPosition(BasicBlock *block, bool atTail)
}
void
-BuildUtil::setPosition(Instruction *i, bool after)
+BuildUtil::setPosition(BaseInstruction *i, bool after)
{
bb = i->bb;
prog = bb->getProgram();
@@ -241,7 +241,7 @@ BuildUtil::getSSA(int size, DataFile f)
return lval;
}
-void BuildUtil::insert(Instruction *i)
+void BuildUtil::insert(BaseInstruction *i)
{
if (!pos) {
tail ? bb->insertTail(i) : bb->insertHead(i);
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
index 26826d6360..036329d5e0 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
@@ -3722,7 +3722,7 @@ SchedDataCalculatorGM107::getWtDepBar(const Instruction *insn) const
void
SchedDataCalculatorGM107::setReuseFlag(Instruction *insn)
{
- Instruction *next = insn->next;
+ Instruction *next = insn->getNext();
BitSet defs(255, 1);
if (!targ->isReuseSupported(insn))
@@ -3999,8 +3999,8 @@ SchedDataCalculatorGM107::findFirstUse(const Instruction *bari) const
if (!bari->defExists(0))
return NULL;
- for (insn = bari->next; insn != NULL; insn = next) {
- next = insn->next;
+ for (insn = bari->getNext(); insn != NULL; insn = next) {
+ next = insn->getNext();
for (int s = 0; insn->srcExists(s); ++s)
if (doesInsnWriteTo(bari, insn->getSrc(s)))
@@ -4023,8 +4023,8 @@ SchedDataCalculatorGM107::findFirstDef(const Instruction *bari) const
if (!bari->srcExists(0))
return NULL;
- for (insn = bari->next; insn != NULL; insn = next) {
- next = insn->next;
+ for (insn = bari->getNext(); insn != NULL; insn = next) {
+ next = insn->getNext();
for (int s = 0; bari->srcExists(s); ++s)
if (doesInsnWriteTo(insn, bari->getSrc(s)))
@@ -4052,7 +4052,7 @@ SchedDataCalculatorGM107::insertBarriers(BasicBlock *bb)
Instruction *usei = NULL, *defi = NULL;
bool need_wr_bar, need_rd_bar;
- next = insn->next;
+ next = insn->getNext();
// Expire old barrier uses.
for (std::list<LiveBarUse>::iterator it = live_uses.begin();
@@ -4125,7 +4125,7 @@ SchedDataCalculatorGM107::insertBarriers(BasicBlock *bb)
for (insn = bb->getEntry(); insn != NULL; insn = next) {
int wr, rd, wt;
- next = insn->next;
+ next = insn->getNext();
wr = getWrDepBar(insn);
rd = getRdDepBar(insn);
@@ -4169,7 +4169,7 @@ SchedDataCalculatorGM107::visit(BasicBlock *bb)
Instruction *insn, *next = NULL;
int cycle = 0;
- for (Instruction *insn = bb->getEntry(); insn; insn = insn->next) {
+ for (Instruction *insn = bb->getEntry(); insn; insn = insn->getNext()) {
/*XXX*/
insn->sched = 0x7e0;
}
@@ -4208,8 +4208,8 @@ SchedDataCalculatorGM107::visit(BasicBlock *bb)
emitWtDepBar(start, b);
}
- for (insn = bb->getEntry(); insn && insn->next; insn = insn->next) {
- next = insn->next;
+ for (insn = bb->getEntry(); insn && insn->next; insn = insn->getNext()) {
+ next = insn->getNext();
commitInsn(insn, cycle);
int delay = calcDelay(next, cycle);
@@ -4258,8 +4258,8 @@ SchedDataCalculatorGM107::visit(BasicBlock *bb)
} else {
// Wait until all dependencies are satisfied.
const int regsFree = score->getLatest();
- next = out->getFirst();
- for (int c = cycle; next && c < regsFree; next = next->next) {
+ next = out->getEntry();
+ for (int c = cycle; next && c < regsFree; next = next->getNext()) {
bbDelay = MAX2(bbDelay, calcDelay(next, c));
c += getStall(next);
}
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp
index 139ff4a31d..49b3bc8ec6 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp
@@ -2126,15 +2126,15 @@ makeInstructionLong(Instruction *insn)
int n = 0;
int adj = 4;
- for (Instruction *i = insn->next; i && i->encSize == 4; ++n, i = i->next);
+ for (Instruction *i = insn->getNext(); i && i->encSize == 4; ++n, i = i->getNext());
if (n & 1) {
adj = 8;
- insn->next->encSize = 8;
+ insn->getNext()->encSize = 8;
} else
- if (insn->prev && insn->prev->encSize == 4) {
+ if (insn->getPrev() && insn->getPrev()->encSize == 4) {
adj = 8;
- insn->prev->encSize = 8;
+ insn->getPrev()->encSize = 8;
}
insn->encSize = 8;
@@ -2146,7 +2146,7 @@ makeInstructionLong(Instruction *insn)
}
static bool
-trySetExitModifier(Instruction *insn)
+trySetExitModifier(BaseInstruction *insn)
{
if (insn->op == OP_DISCARD ||
insn->op == OP_QUADON ||
@@ -2158,12 +2158,12 @@ trySetExitModifier(Instruction *insn)
if (insn->asFlow()) {
if (insn->op == OP_CALL) // side effects !
return false;
- if (insn->getPredicate()) // cannot do conditional exit (or can we ?)
+ if (asInsn(insn)->getPredicate()) // cannot do conditional exit (or can we ?)
return false;
insn->op = OP_EXIT;
}
- insn->exit = 1;
- makeInstructionLong(insn);
+ asInsn(insn)->exit = 1;
+ makeInstructionLong(asInsn(insn));
return true;
}
@@ -2177,22 +2177,22 @@ replaceExitWithModifier(Function *func)
return;
if (epilogue->getEntry()->op != OP_EXIT) {
- Instruction *insn = epilogue->getExit()->prev;
+ BaseInstruction *insn = epilogue->getExit();
if (!insn || !trySetExitModifier(insn))
return;
- insn->exit = 1;
+ asInsn(insn)->exit = 1;
} else {
for (Graph::EdgeIterator ei = func->cfgExit->incident();
!ei.end(); ei.next()) {
BasicBlock *bb = BasicBlock::get(ei.getNode());
- Instruction *i = bb->getExit();
+ BaseInstruction *i = bb->getExit();
if (!i || !trySetExitModifier(i))
return;
}
}
- int adj = epilogue->getExit()->encSize;
+ int adj = asInsn(epilogue->getExit())->encSize;
epilogue->binSize -= adj;
func->binSize -= adj;
delete_Instruction(func->getProgram(), epilogue->getExit());
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
index d85fdda56f..7fde0f1001 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
@@ -3245,7 +3245,7 @@ SchedDataCalculator::visit(BasicBlock *bb)
BasicBlock *in = BasicBlock::get(ei.getNode());
if (in->getExit()) {
if (prevData != 0x04)
- prevData = in->getExit()->sched;
+ prevData = asInsn(in->getExit())->sched;
prevOp = in->getExit()->op;
}
score->setMax(&scoreBoards.at(in->getId()));
@@ -3258,8 +3258,8 @@ SchedDataCalculator::visit(BasicBlock *bb)
score->print(cycle);
#endif
- for (insn = bb->getEntry(); insn && insn->next; insn = insn->next) {
- next = insn->next;
+ for (insn = bb->getEntry(); insn && insn->next; insn = insn->getNext()) {
+ next = insn->getNext();
commitInsn(insn, cycle);
int delay = calcDelay(next, cycle);
@@ -3289,8 +3289,8 @@ SchedDataCalculator::visit(BasicBlock *bb)
} else {
// wait until all dependencies are satisfied
const int regsFree = score->getLatest();
- next = out->getFirst();
- for (int c = cycle; next && c < regsFree; next = next->next) {
+ next = out->getEntry();
+ for (int c = cycle; next && c < regsFree; next = next->getNext()) {
bbDelay = MAX2(bbDelay, calcDelay(next, c));
c += getCycles(next, bbDelay);
}
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
index 2f9bcc1f34..854301b644 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
@@ -1987,7 +1987,7 @@ Converter::fetchSrc(int s, int c)
res = fetchSrc(src, c, ptr);
if (dimRel)
- res->getInsn()->setIndirect(0, 1, dimRel);
+ asInsn(res->getInsn())->setIndirect(0, 1, dimRel);
return applySrcMod(res, s, c);
}
@@ -2028,7 +2028,7 @@ Converter::fetchDst(int d, int c)
res = fetchSrc(src, c, ptr);
if (dimRel)
- res->getInsn()->setIndirect(0, 1, dimRel);
+ asInsn(res->getInsn())->setIndirect(0, 1, dimRel);
return res;
}
@@ -2337,7 +2337,7 @@ void
Converter::loadProjTexCoords(Value *dst[4], Value *src[4], unsigned int mask)
{
Value *proj = fetchSrc(0, 3);
- Instruction *insn = proj->getUniqueInsn();
+ Instruction *insn = asInsn(proj->getUniqueInsn());
int c;
if (insn->op == OP_PINTERP) {
@@ -2352,7 +2352,7 @@ Converter::loadProjTexCoords(Value *dst[4], Value *src[4], unsigned int mask)
for (c = 0; c < 4; ++c) {
if (!(mask & (1 << c)))
continue;
- if ((insn = src[c]->getUniqueInsn())->op != OP_PINTERP)
+ if ((insn = asInsn(src[c]->getUniqueInsn()))->op != OP_PINTERP)
continue;
mask &= ~(1 << c);
@@ -3074,10 +3074,10 @@ Converter::handleINTERP(Value *dst[4])
FOR_EACH_DST_ENABLED_CHANNEL(0, c, tgsi) {
Value *val = fetchSrc(0, c);
assert(val->defs.size() == 1);
- insn = val->getInsn();
+ insn = asInsn(val->getInsn());
while (insn->op == OP_MOV) {
assert(insn->getSrc(0)->defs.size() == 1);
- insn = insn->getSrc(0)->getInsn();
+ insn = asInsn(insn->getSrc(0)->getInsn());
if (!insn) {
ERROR("Miscompiling shader due to unhandled INTERP\n");
return;
@@ -4375,8 +4375,8 @@ Converter::BindArgumentsPass::visit(Function *f)
for (ArrayList::Iterator bi = f->allBBlocks.iterator();
!bi.end(); bi.next()) {
- for (Instruction *i = BasicBlock::get(bi)->getFirst();
- i; i = i->next) {
+ for (Instruction *i = BasicBlock::get(bi)->getEntry();
+ i; i = i->getNext()) {
if (i->op == OP_CALL && !i->asFlow()->builtin) {
updateCallArgs(i, &Instruction::setSrc, &Function::ins);
updateCallArgs(i, &Instruction::setDef, &Function::outs);
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h
index 4cb53ab42e..5d19614d4a 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h
@@ -205,12 +205,12 @@ const LValue *ValueDef::preSSA() const
return origin;
}
-Instruction *Value::getInsn() const
+BaseInstruction *Value::getInsn() const
{
return defs.empty() ? NULL : defs.front()->getInsn();
}
-Instruction *Value::getUniqueInsn() const
+BaseInstruction *Value::getUniqueInsn() const
{
if (defs.empty())
return NULL;
@@ -236,12 +236,12 @@ Instruction *Value::getUniqueInsn() const
return defs.front()->getInsn();
}
-inline bool Instruction::constrainedDefs() const
+inline bool BaseInstruction::constrainedDefs() const
{
return defExists(1) || op == OP_UNION;
}
-Value *Instruction::getIndirect(int s, int dim) const
+Value *BaseInstruction::getIndirect(int s, int dim) const
{
return srcs[s].isIndirect(dim) ? getSrc(srcs[s].indirect[dim]) : NULL;
}
@@ -281,49 +281,77 @@ Value *TexInstruction::getIndirectS() const
return tex.rIndirectSrc >= 0 ? getSrc(tex.rIndirectSrc) : NULL;
}
-CmpInstruction *Instruction::asCmp()
+CmpInstruction *BaseInstruction::asCmp()
{
if (op >= OP_SET_AND && op <= OP_SLCT && op != OP_SELP)
return static_cast<CmpInstruction *>(this);
return NULL;
}
-const CmpInstruction *Instruction::asCmp() const
+const CmpInstruction *BaseInstruction::asCmp() const
{
if (op >= OP_SET_AND && op <= OP_SLCT && op != OP_SELP)
return static_cast<const CmpInstruction *>(this);
return NULL;
}
-FlowInstruction *Instruction::asFlow()
+FlowInstruction *BaseInstruction::asFlow()
{
if (op >= OP_BRA && op <= OP_JOIN)
return static_cast<FlowInstruction *>(this);
return NULL;
}
-const FlowInstruction *Instruction::asFlow() const
+const FlowInstruction *BaseInstruction::asFlow() const
{
if (op >= OP_BRA && op <= OP_JOIN)
return static_cast<const FlowInstruction *>(this);
return NULL;
}
-TexInstruction *Instruction::asTex()
+TexInstruction *BaseInstruction::asTex()
{
if ((op >= OP_TEX && op <= OP_SULEA) || op == OP_SUQ)
return static_cast<TexInstruction *>(this);
return NULL;
}
-const TexInstruction *Instruction::asTex() const
+const TexInstruction *BaseInstruction::asTex() const
{
if ((op >= OP_TEX && op <= OP_SULEA) || op == OP_SUQ)
return static_cast<const TexInstruction *>(this);
return NULL;
}
-static inline Instruction *cloneForward(Function *ctx, Instruction *obj)
+static inline PhiInstruction *asPhi(BaseInstruction *i)
+{
+ if (!i)
+ return NULL;
+ return i->op == OP_PHI ? static_cast<PhiInstruction *>(i) : NULL;
+}
+
+static inline const PhiInstruction *asPhi(const BaseInstruction *i)
+{
+ if (!i)
+ return NULL;
+ return i->op == OP_PHI ? static_cast<const PhiInstruction *>(i) : NULL;
+}
+
+static inline Instruction *asInsn(BaseInstruction *i)
+{
+ if (!i)
+ return NULL;
+ return i->op == OP_PHI ? NULL : static_cast<Instruction *>(i);
+}
+
+static inline const Instruction *asInsn(const BaseInstruction *i)
+{
+ if (!i)
+ return NULL;
+ return i->op == OP_PHI ? NULL : static_cast<const Instruction *>(i);
+}
+
+static inline BaseInstruction *cloneForward(Function *ctx, const BaseInstruction *obj)
{
DeepClonePolicy<Function> pol(ctx);
@@ -333,6 +361,11 @@ static inline Instruction *cloneForward(Function *ctx, Instruction *obj)
return obj->clone(pol);
}
+static inline Instruction *cloneForward(Function *ctx, const Instruction *obj)
+{
+ return asInsn(cloneForward(ctx, static_cast<const BaseInstruction *>(obj)));
+}
+
// XXX: use a virtual function so we're really really safe ?
LValue *Value::asLValue()
{
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nv50.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nv50.cpp
index 36ab837f6e..e47b36a158 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nv50.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nv50.cpp
@@ -294,7 +294,7 @@ NV50LegalizePostRA::handlePRERET(FlowInstruction *pre)
bool
NV50LegalizePostRA::visit(BasicBlock *bb)
{
- Instruction *i, *next;
+ BaseInstruction *i, *next;
// remove pseudo operations and non-fixed no-ops, split 64 bit operations
for (i = bb->getFirst(); i; i = next) {
@@ -308,14 +308,14 @@ NV50LegalizePostRA::visit(BasicBlock *bb)
// TODO: We will want to do this before register allocation,
// since have to use a $c register for the carry flag.
if (typeSizeof(i->dType) == 8) {
- Instruction *hi = BuildUtil::split64BitOpPostRA(func, i, r63, NULL);
+ Instruction *hi = BuildUtil::split64BitOpPostRA(func, asInsn(i), r63, NULL);
if (hi)
next = hi;
}
if (i->op != OP_PFETCH && i->op != OP_BAR &&
(!i->defExists(0) || i->def(0).getFile() != FILE_ADDRESS))
- replaceZero(i);
+ replaceZero(asInsn(i));
}
}
if (!bb->getEntry())
@@ -338,7 +338,7 @@ private:
void handleMUL(Instruction *);
void handleAddrDef(Instruction *);
- inline bool isARL(const Instruction *) const;
+ inline bool isARL(const BaseInstruction *) const;
BuildUtil bld;
@@ -365,7 +365,7 @@ NV50LegalizeSSA::propagateWriteToOutput(Instruction *st)
return;
// check def instruction can store
- Instruction *di = st->getSrc(1)->defs.front()->getInsn();
+ BaseInstruction *di = st->getSrc(1)->defs.front()->getInsn();
// TODO: move exports (if beneficial) in common opt pass
if (di->isPseudo() || isTextureOp(di->op) || di->defCount(0xff, true) > 1)
@@ -381,7 +381,7 @@ NV50LegalizeSSA::propagateWriteToOutput(Instruction *st)
// that we are propagating to the same output vertex.
if (di->bb != st->bb)
return;
- Instruction *i;
+ BaseInstruction *i;
for (i = di; i != st; i = i->next) {
if (i->op == OP_EMIT || i->op == OP_RESTART)
return;
@@ -396,7 +396,7 @@ NV50LegalizeSSA::propagateWriteToOutput(Instruction *st)
}
bool
-NV50LegalizeSSA::isARL(const Instruction *i) const
+NV50LegalizeSSA::isARL(const BaseInstruction *i) const
{
ImmediateValue imm;
@@ -475,7 +475,7 @@ NV50LegalizeSSA::handleMUL(Instruction *mul)
}
expandIntegerMUL(&bld, mul);
if (pred)
- def->getInsn()->setPredicate(cc, pred);
+ asInsn(def->getInsn())->setPredicate(cc, pred);
}
// Use f32 division: first compute an approximate result, use it to reduce
@@ -500,8 +500,8 @@ NV50LegalizeSSA::handleDIV(Instruction *div)
bld.mkCvt(OP_CVT, TYPE_F32, bf, ty, div->getSrc(1));
if (isSignedType(ty)) {
- af->getInsn()->src(0).mod = Modifier(NV50_IR_MOD_ABS);
- bf->getInsn()->src(0).mod = Modifier(NV50_IR_MOD_ABS);
+ asInsn(af->getInsn())->src(0).mod = Modifier(NV50_IR_MOD_ABS);
+ asInsn(bf->getInsn())->src(0).mod = Modifier(NV50_IR_MOD_ABS);
a = bld.getSSA();
b = bld.getSSA();
bld.mkOp1(OP_ABS, ty, a, div->getSrc(0));
@@ -566,7 +566,7 @@ NV50LegalizeSSA::handleMOD(Instruction *mod)
Value *m = bld.getSSA();
bld.mkOp2(OP_DIV, mod->dType, q, mod->getSrc(0), mod->getSrc(1));
- handleDIV(q->getInsn());
+ handleDIV(asInsn(q->getInsn()));
bld.setPosition(mod, false);
expandIntegerMUL(&bld, bld.mkOp2(OP_MUL, TYPE_U32, m, q, mod->getSrc(1)));
@@ -581,7 +581,7 @@ NV50LegalizeSSA::visit(BasicBlock *bb)
Instruction *insn, *next;
// skipping PHIs (don't pass them to handleAddrDef) !
for (insn = bb->getEntry(); insn; insn = next) {
- next = insn->next;
+ next = insn->getNext();
if (insn->defExists(0) && insn->getDef(0)->reg.file == FILE_ADDRESS)
handleAddrDef(insn);
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
index 597dcdffbe..4b76d69405 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
@@ -50,7 +50,7 @@ NVC0LegalizeSSA::handleDIV(Instruction *i)
// Generate movs to the input regs for the call we want to generate
for (int s = 0; i->srcExists(s); ++s) {
- Instruction *ld = i->getSrc(s)->getInsn();
+ BaseInstruction *ld = i->getSrc(s)->getInsn();
assert(ld->getSrc(0) != NULL);
// check if we are moving an immediate, propagate it in that case
if (!ld || ld->fixed || (ld->op != OP_LOAD && ld->op != OP_MOV) ||
@@ -284,7 +284,7 @@ NVC0LegalizeSSA::visit(BasicBlock *bb)
{
Instruction *next;
for (Instruction *i = bb->getEntry(); i; i = next) {
- next = i->next;
+ next = i->getNext();
if (i->sType == TYPE_F32 && prog->getType() != Program::TYPE_COMPUTE)
handleFTZ(i);
@@ -333,8 +333,8 @@ NVC0LegalizePostRA::NVC0LegalizePostRA(const Program *prog)
}
bool
-NVC0LegalizePostRA::insnDominatedBy(const Instruction *later,
- const Instruction *early) const
+NVC0LegalizePostRA::insnDominatedBy(const BaseInstruction *later,
+ const BaseInstruction *early) const
{
if (early->bb == later->bb)
return early->serial < later->serial;
@@ -343,7 +343,7 @@ NVC0LegalizePostRA::insnDominatedBy(const Instruction *later,
void
NVC0LegalizePostRA::addTexUse(std::list<TexUse> &uses,
- Instruction *usei, const Instruction *texi)
+ BaseInstruction *usei, const BaseInstruction *texi)
{
bool add = true;
bool dominated = insnDominatedBy(usei, texi);
@@ -383,7 +383,7 @@ NVC0LegalizePostRA::addTexUse(std::list<TexUse> &uses,
// instructions looking for ones that reference the registers in question.
void
NVC0LegalizePostRA::findFirstUses(
- Instruction *texi, std::list<TexUse> &uses)
+ BaseInstruction *texi, std::list<TexUse> &uses)
{
int minGPR = texi->def(0).rep()->reg.data.id;
int maxGPR = minGPR + texi->def(0).rep()->reg.size / 4 - 1;
@@ -394,8 +394,8 @@ NVC0LegalizePostRA::findFirstUses(
void
NVC0LegalizePostRA::findFirstUsesBB(
- int minGPR, int maxGPR, Instruction *start,
- const Instruction *texi, std::list<TexUse> &uses,
+ int minGPR, int maxGPR, BaseInstruction *start,
+ const BaseInstruction *texi, std::list<TexUse> &uses,
unordered_set<const BasicBlock *> &visited)
{
const BasicBlock *bb = start->bb;
@@ -410,7 +410,7 @@ NVC0LegalizePostRA::findFirstUsesBB(
visited.insert(bb);
}
- for (Instruction *insn = start; insn != bb->getExit(); insn = insn->next) {
+ for (BaseInstruction *insn = start; insn != bb->getExit(); insn = insn->next) {
if (insn->isNop())
continue;
@@ -529,10 +529,10 @@ NVC0LegalizePostRA::insertTextureBarriers(Function *fn)
// insert the barriers
for (size_t i = 0; i < useVec.size(); ++i) {
- Instruction *prev = useVec[i].insn->prev;
if (useVec[i].level < 0)
continue;
- if (prev && prev->op == OP_TEXBAR) {
+ if (useVec[i].insn->prev && useVec[i].insn->prev->op == OP_TEXBAR) {
+ Instruction *prev = asInsn(useVec[i].insn->prev);
if (prev->subOp > useVec[i].level)
prev->subOp = useVec[i].level;
prev->setSrc(prev->srcCount(), useVec[i].tex->getDef(0));
@@ -563,7 +563,7 @@ NVC0LegalizePostRA::insertTextureBarriers(Function *fn)
BasicBlock *bb = BasicBlock::get(n);
int min = 0;
int max = std::numeric_limits<int>::max();
- for (Instruction *i = bb->getFirst(); i; i = i->next) {
+ for (Instruction *i = bb->getEntry(); i; i = i->getNext()) {
if (isTextureOp(i->op)) {
min++;
if (max < std::numeric_limits<int>::max())
@@ -611,8 +611,8 @@ NVC0LegalizePostRA::insertTextureBarriers(Function *fn)
Instruction *prev = NULL;
Instruction *next;
int max = limitT[bb->getId()].max;
- for (Instruction *i = bb->getFirst(); i; i = next) {
- next = i->next;
+ for (Instruction *i = bb->getEntry(); i; i = next) {
+ next = i->getNext();
if (i->op == OP_TEXBAR) {
if (i->subOp >= max) {
delete_Instruction(prog, i);
@@ -687,7 +687,7 @@ NVC0LegalizePostRA::tryReplaceContWithBra(BasicBlock *bb)
BasicBlock *contBB = BasicBlock::get(ei.getNode());
if (!contBB->getExit() || contBB->getExit()->op != OP_CONT ||
- contBB->getExit()->getPredicate())
+ asInsn(contBB->getExit())->getPredicate())
return false;
contBB->getExit()->op = OP_BRA;
bb->remove(bb->getEntry()); // delete PRECONT
@@ -705,7 +705,7 @@ NVC0LegalizePostRA::propagateJoin(BasicBlock *bb)
return;
for (Graph::EdgeIterator ei = bb->cfg.incident(); !ei.end(); ei.next()) {
BasicBlock *in = BasicBlock::get(ei.getNode());
- Instruction *exit = in->getExit();
+ BaseInstruction *exit = in->getExit();
if (!exit) {
in->insertTail(new FlowInstruction(func, OP_JOIN, bb));
// there should always be a terminator instruction
@@ -722,7 +722,7 @@ NVC0LegalizePostRA::propagateJoin(BasicBlock *bb)
bool
NVC0LegalizePostRA::visit(BasicBlock *bb)
{
- Instruction *i, *next;
+ BaseInstruction *i, *next;
// remove pseudo operations and non-fixed no-ops, split 64 bit operations
for (i = bb->getFirst(); i; i = next) {
@@ -731,19 +731,19 @@ NVC0LegalizePostRA::visit(BasicBlock *bb)
if (!i->getDef(0)->refCount())
i->setDef(0, NULL);
if (i->src(0).getFile() == FILE_IMMEDIATE)
- i->setSrc(0, rZero); // initial value must be 0
- replaceZero(i);
+ asInsn(i)->setSrc(0, rZero); // initial value must be 0
+ replaceZero(asInsn(i));
} else
if (i->isNop()) {
bb->remove(i);
} else
- if (i->op == OP_BAR && i->subOp == NV50_IR_SUBOP_BAR_SYNC &&
+ if (i->op == OP_BAR && asInsn(i)->subOp == NV50_IR_SUBOP_BAR_SYNC &&
prog->getType() != Program::TYPE_COMPUTE) {
// It seems like barriers are never required for tessellation since
// the warp size is 32, and there are always at most 32 tcs threads.
bb->remove(i);
} else
- if (i->op == OP_LOAD && i->subOp == NV50_IR_SUBOP_LDC_IS) {
+ if (i->op == OP_LOAD && asInsn(i)->subOp == NV50_IR_SUBOP_LDC_IS) {
int offset = i->src(0).get()->reg.data.offset;
if (abs(offset) >= 0x10000)
i->src(0).get()->reg.fileIndex += offset >> 16;
@@ -753,13 +753,13 @@ NVC0LegalizePostRA::visit(BasicBlock *bb)
// need the $c register !
if (typeSizeof(i->sType) == 8 || typeSizeof(i->dType) == 8) {
Instruction *hi;
- hi = BuildUtil::split64BitOpPostRA(func, i, rZero, carry);
+ hi = BuildUtil::split64BitOpPostRA(func, asInsn(i), rZero, carry);
if (hi)
next = hi;
}
if (i->op != OP_MOV && i->op != OP_PFETCH)
- replaceZero(i);
+ replaceZero(asInsn(i));
}
}
if (!bb->getEntry())
@@ -1889,11 +1889,11 @@ NVC0LoweringPass::processSurfaceCoordsNVE4(TexInstruction *su)
// set predicate output
if (su->tex.target == TEX_TARGET_BUFFER) {
- src[0]->getInsn()->setFlagsDef(1, pred);
+ asInsn(src[0]->getInsn())->setFlagsDef(1, pred);
} else
if (su->tex.target.isArray() || su->tex.target.isCube()) {
p1 = bld.getSSA(1, FILE_PREDICATE);
- src[dim]->getInsn()->setFlagsDef(1, p1);
+ asInsn(src[dim]->getInsn())->setFlagsDef(1, p1);
}
// calculate pixel offset
@@ -2801,7 +2801,7 @@ NVC0LoweringPass::handleEXPORT(Instruction *i)
bool
NVC0LoweringPass::handleOUT(Instruction *i)
{
- Instruction *prev = i->prev;
+ BaseInstruction *prev = i->prev;
ImmediateValue stream, prevStream;
// Only merge if the stream ids match. Also, note that the previous
@@ -2810,7 +2810,7 @@ NVC0LoweringPass::handleOUT(Instruction *i)
i->src(0).getImmediate(stream) &&
prev->src(1).getImmediate(prevStream) &&
stream.reg.data.u32 == prevStream.reg.data.u32) {
- i->prev->subOp = NV50_IR_SUBOP_EMIT_RESTART;
+ asInsn(i->prev)->subOp = NV50_IR_SUBOP_EMIT_RESTART;
delete_Instruction(prog, i);
} else {
assert(gpEmitAddress);
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h
index 8724c09afd..8f590ee050 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h
@@ -87,10 +87,10 @@ private:
struct TexUse
{
- TexUse(Instruction *use, const Instruction *tex, bool after)
+ TexUse(BaseInstruction *use, const BaseInstruction *tex, bool after)
: insn(use), tex(tex), after(after), level(-1) { }
- Instruction *insn;
- const Instruction *tex; // or split / mov
+ BaseInstruction *insn;
+ const BaseInstruction *tex; // or split / mov
bool after;
int level;
};
@@ -101,12 +101,12 @@ private:
int min, max;
};
bool insertTextureBarriers(Function *);
- inline bool insnDominatedBy(const Instruction *, const Instruction *) const;
- void findFirstUses(Instruction *texi, std::list<TexUse> &uses);
- void findFirstUsesBB(int minGPR, int maxGPR, Instruction *start,
- const Instruction *texi, std::list<TexUse> &uses,
+ inline bool insnDominatedBy(const BaseInstruction *, const BaseInstruction *) const;
+ void findFirstUses(BaseInstruction *texi, std::list<TexUse> &uses);
+ void findFirstUsesBB(int minGPR, int maxGPR, BaseInstruction *start,
+ const BaseInstruction *texi, std::list<TexUse> &uses,
unordered_set<const BasicBlock *> &visited);
- void addTexUse(std::list<TexUse>&, Instruction *, const Instruction *);
+ void addTexUse(std::list<TexUse>&, BaseInstruction *, const BaseInstruction *);
const Instruction *recurseDef(const Instruction *);
private:
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp
index 39177bd044..0ec8fd1898 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp
@@ -31,7 +31,7 @@ extern "C" {
namespace nv50_ir {
bool
-Instruction::isNop() const
+BaseInstruction::isNop() const
{
if (op == OP_PHI || op == OP_SPLIT || op == OP_MERGE || op == OP_CONSTRAINT)
return true;
@@ -61,7 +61,8 @@ Instruction::isNop() const
return false;
}
-bool Instruction::isDead() const
+bool
+BaseInstruction::isDead() const
{
if (op == OP_STORE ||
op == OP_EXPORT ||
@@ -96,10 +97,11 @@ private:
bool
CopyPropagation::visit(BasicBlock *bb)
{
- Instruction *mov, *si, *next;
+ Instruction *mov, *next;
+ BaseInstruction *si;
for (mov = bb->getEntry(); mov; mov = next) {
- next = mov->next;
+ next = mov->getNext();
if (mov->op != OP_MOV || mov->fixed || !mov->getSrc(0)->asLValue())
continue;
if (mov->getPredicate())
@@ -129,10 +131,11 @@ private:
bool
MergeSplits::visit(BasicBlock *bb)
{
- Instruction *i, *next, *si;
+ Instruction *i, *next;
+ BaseInstruction *si;
for (i = bb->getEntry(); i; i = next) {
- next = i->next;
+ next = i->getNext();
if (i->op != OP_MERGE || typeSizeof(i->dType) != 8)
continue;
si = i->getSrc(0)->getInsn();
@@ -154,19 +157,19 @@ private:
void checkSwapSrc01(Instruction *);
- bool isCSpaceLoad(Instruction *);
- bool isImmdLoad(Instruction *);
- bool isAttribOrSharedLoad(Instruction *);
+ bool isCSpaceLoad(BaseInstruction *);
+ bool isImmdLoad(BaseInstruction *);
+ bool isAttribOrSharedLoad(BaseInstruction *);
};
bool
-LoadPropagation::isCSpaceLoad(Instruction *ld)
+LoadPropagation::isCSpaceLoad(BaseInstruction *ld)
{
return ld && ld->op == OP_LOAD && ld->src(0).getFile() == FILE_MEMORY_CONST;
}
bool
-LoadPropagation::isImmdLoad(Instruction *ld)
+LoadPropagation::isImmdLoad(BaseInstruction *ld)
{
if (!ld || (ld->op != OP_MOV) ||
((typeSizeof(ld->dType) != 4) && (typeSizeof(ld->dType) != 8)))
@@ -178,7 +181,7 @@ LoadPropagation::isImmdLoad(Instruction *ld)
}
bool
-LoadPropagation::isAttribOrSharedLoad(Instruction *ld)
+LoadPropagation::isAttribOrSharedLoad(BaseInstruction *ld)
{
return ld &&
(ld->op == OP_VFETCH ||
@@ -201,17 +204,17 @@ LoadPropagation::checkSwapSrc01(Instruction *insn)
if (insn->op == OP_SET && insn->subOp)
return;
- Instruction *i0 = insn->getSrc(0)->getInsn();
- Instruction *i1 = insn->getSrc(1)->getInsn();
+ BaseInstruction *i0 = insn->getSrc(0)->getInsn();
+ BaseInstruction *i1 = insn->getSrc(1)->getInsn();
// Swap sources to inline the less frequently used source. That way,
// optimistically, it will eventually be able to remove the instruction.
int i0refs = insn->getSrc(0)->refCount();
int i1refs = insn->getSrc(1)->refCount();
- if ((isCSpaceLoad(i0) || isImmdLoad(i0)) && targ->insnCanLoad(insn, 1, i0)) {
+ if ((isCSpaceLoad(i0) || isImmdLoad(i0)) && targ->insnCanLoad(insn, 1, asInsn(i0))) {
if ((!isImmdLoad(i1) && !isCSpaceLoad(i1)) ||
- !targ->insnCanLoad(insn, 1, i1) ||
+ !targ->insnCanLoad(insn, 1, asInsn(i1)) ||
i0refs < i1refs)
insn->swapSources(0, 1);
else
@@ -246,7 +249,7 @@ LoadPropagation::visit(BasicBlock *bb)
Instruction *next;
for (Instruction *i = bb->getEntry(); i; i = next) {
- next = i->next;
+ next = i->getNext();
if (i->op == OP_CALL) // calls have args as sources, they must be in regs
continue;
@@ -258,11 +261,11 @@ LoadPropagation::visit(BasicBlock *bb)
checkSwapSrc01(i);
for (int s = 0; i->srcExists(s); ++s) {
- Instruction *ld = i->getSrc(s)->getInsn();
+ BaseInstruction *ld = i->getSrc(s)->getInsn();
if (!ld || ld->fixed || (ld->op != OP_LOAD && ld->op != OP_MOV))
continue;
- if (!targ->insnCanLoad(i, s, ld))
+ if (!targ->insnCanLoad(i, s, asInsn(ld)))
continue;
// propagate !
@@ -292,10 +295,10 @@ IndirectPropagation::visit(BasicBlock *bb)
Instruction *next;
for (Instruction *i = bb->getEntry(); i; i = next) {
- next = i->next;
+ next = i->getNext();
for (int s = 0; i->srcExists(s); ++s) {
- Instruction *insn;
+ BaseInstruction *insn;
ImmediateValue imm;
if (!i->src(s).isIndirect(0))
continue;
@@ -377,7 +380,7 @@ ConstantFolding::visit(BasicBlock *bb)
Instruction *i, *next;
for (i = bb->getEntry(); i; i = next) {
- next = i->next;
+ next = i->getNext();
if (i->op == OP_MOV || i->op == OP_CALL)
continue;
@@ -409,7 +412,7 @@ ConstantFolding::findOriginForTestWithZero(Value *value)
{
if (!value)
return NULL;
- Instruction *insn = value->getInsn();
+ BaseInstruction *insn = value->getInsn();
if (!insn)
return NULL;
@@ -841,7 +844,7 @@ ConstantFolding::tryCollapseChainedMULs(Instruction *mul2,
const int s, ImmediateValue& imm2)
{
const int t = s ? 0 : 1;
- Instruction *insn;
+ BaseInstruction *insn;
Instruction *mul1 = NULL; // mul1 before mul2
int e = 0;
float f = imm2.reg.data.f32 * exp2f(mul2->postFactor);
@@ -852,7 +855,7 @@ ConstantFolding::tryCollapseChainedMULs(Instruction *mul2,
if (mul2->getSrc(t)->refCount() == 1) {
insn = mul2->getSrc(t)->getInsn();
if (!mul2->src(t).mod && insn->op == OP_MUL && insn->dType == TYPE_F32)
- mul1 = insn;
+ mul1 = asInsn(insn);
if (mul1 && !mul1->saturate) {
int s1;
@@ -891,7 +894,7 @@ ConstantFolding::tryCollapseChainedMULs(Instruction *mul2,
t2 = s2 ? 0 : 1;
if (insn->op == OP_MUL && insn->dType == TYPE_F32)
if (!insn->src(s2).mod && !insn->src(t2).getImmediate(imm1))
- mul2 = insn;
+ mul2 = asInsn(insn);
if (mul2 && prog->getTarget()->isPostMultiplySupported(OP_MUL, f, e)) {
mul2->postFactor = e;
mul2->setSrc(s2, mul1->src(t));
@@ -1264,7 +1267,7 @@ ConstantFolding::opnd(Instruction *i, ImmediateValue &imm0, int s)
case OP_AND:
{
- Instruction *src = i->getSrc(t)->getInsn();
+ BaseInstruction *src = i->getSrc(t)->getInsn();
ImmediateValue imm1;
if (imm0.reg.data.u32 == 0) {
i->op = OP_MOV;
@@ -1331,7 +1334,7 @@ ConstantFolding::opnd(Instruction *i, ImmediateValue &imm0, int s)
if (s != 1 || i->src(0).mod != Modifier(0))
break;
// try to concatenate shifts
- Instruction *si = i->getSrc(0)->getInsn();
+ BaseInstruction *si = i->getSrc(0)->getInsn();
if (!si)
break;
ImmediateValue imm1;
@@ -1585,7 +1588,7 @@ ModifierFolding::visit(BasicBlock *bb)
Modifier mod;
for (i = bb->getEntry(); i; i = next) {
- next = i->next;
+ next = i->getNext();
if (0 && i->op == OP_SUB) {
// turn "sub" into "add neg" (do we really want this ?)
@@ -1594,7 +1597,7 @@ ModifierFolding::visit(BasicBlock *bb)
}
for (int s = 0; s < 3 && i->srcExists(s); ++s) {
- mi = i->getSrc(s)->getInsn();
+ mi = asInsn(i->getSrc(s)->getInsn());
if (!mi ||
mi->predSrc >= 0 || mi->getDef(0)->refCount() > 8)
continue;
@@ -1634,7 +1637,7 @@ ModifierFolding::visit(BasicBlock *bb)
}
if (i->op == OP_SAT) {
- mi = i->getSrc(0)->getInsn();
+ mi = asInsn(i->getSrc(0)->getInsn());
if (mi &&
mi->getDef(0)->refCount() <= 1 && target->isSatSupported(mi)) {
mi->saturate = 1;
@@ -1678,7 +1681,7 @@ private:
void
AlgebraicOpt::handleABS(Instruction *abs)
{
- Instruction *sub = abs->getSrc(0)->getInsn();
+ BaseInstruction *sub = abs->getSrc(0)->getInsn();
DataType ty;
if (!sub ||
!prog->getTarget()->isOpSupported(OP_SAD, abs->dType))
@@ -1700,7 +1703,7 @@ AlgebraicOpt::handleABS(Instruction *abs)
Value *src1 = sub->getSrc(1);
if (sub->op == OP_ADD) {
- Instruction *neg = sub->getSrc(1)->getInsn();
+ BaseInstruction *neg = sub->getSrc(1)->getInsn();
if (neg && neg->op != OP_NEG) {
neg = sub->getSrc(0)->getInsn();
src0 = sub->getSrc(1);
@@ -1751,6 +1754,7 @@ AlgebraicOpt::tryADDToMADOrSAD(Instruction *add, operation toOp)
const operation srcOp = toOp == OP_SAD ? OP_SAD : OP_MUL;
const Modifier modBad = Modifier(~((toOp == OP_MAD) ? NV50_IR_MOD_NEG : 0));
Modifier mod[4];
+ Instruction *srcInsn;
if (src0->refCount() == 1 &&
src0->getUniqueInsn() && src0->getUniqueInsn()->op == srcOp)
@@ -1763,12 +1767,13 @@ AlgebraicOpt::tryADDToMADOrSAD(Instruction *add, operation toOp)
return false;
src = add->getSrc(s);
+ srcInsn = asInsn(src->getUniqueInsn());
- if (src->getUniqueInsn() && src->getUniqueInsn()->bb != add->bb)
+ if (srcInsn->bb != add->bb)
return false;
- if (src->getInsn()->saturate || src->getInsn()->postFactor ||
- src->getInsn()->dnz || src->getInsn()->precise)
+ if (srcInsn->saturate || srcInsn->postFactor ||
+ srcInsn->dnz || srcInsn->precise)
return false;
if (toOp == OP_SAD) {
@@ -1785,23 +1790,23 @@ AlgebraicOpt::tryADDToMADOrSAD(Instruction *add, operation toOp)
mod[0] = add->src(0).mod;
mod[1] = add->src(1).mod;
- mod[2] = src->getUniqueInsn()->src(0).mod;
- mod[3] = src->getUniqueInsn()->src(1).mod;
+ mod[2] = srcInsn->src(0).mod;
+ mod[3] = srcInsn->src(1).mod;
if (((mod[0] | mod[1]) | (mod[2] | mod[3])) & modBad)
return false;
add->op = toOp;
- add->subOp = src->getInsn()->subOp; // potentially mul-high
- add->dnz = src->getInsn()->dnz;
- add->dType = src->getInsn()->dType; // sign matters for imad hi
- add->sType = src->getInsn()->sType;
+ add->subOp = srcInsn->subOp; // potentially mul-high
+ add->dnz = srcInsn->dnz;
+ add->dType = srcInsn->dType; // sign matters for imad hi
+ add->sType = srcInsn->sType;
add->setSrc(2, add->src(s ? 0 : 1));
- add->setSrc(0, src->getInsn()->getSrc(0));
+ add->setSrc(0, srcInsn->getSrc(0));
add->src(0).mod = mod[2] ^ mod[s];
- add->setSrc(1, src->getInsn()->getSrc(1));
+ add->setSrc(1, srcInsn->getSrc(1));
add->src(1).mod = mod[3];
return true;
@@ -1837,7 +1842,7 @@ AlgebraicOpt::handleMINMAX(Instruction *minmax)
void
AlgebraicOpt::handleRCP(Instruction *rcp)
{
- Instruction *si = rcp->getSrc(0)->getUniqueInsn();
+ BaseInstruction *si = rcp->getSrc(0)->getUniqueInsn();
if (si && si->op == OP_RCP) {
Modifier mod = rcp->src(0).mod * si->src(0).mod;
@@ -1878,13 +1883,13 @@ AlgebraicOpt::handleLOGOP(Instruction *logop)
}
} else {
// try AND(SET, SET) -> SET_AND(SET)
- Instruction *set0 = src0->getInsn();
- Instruction *set1 = src1->getInsn();
+ BaseInstruction *set0 = src0->getInsn();
+ BaseInstruction *set1 = src1->getInsn();
if (!set0 || set0->fixed || !set1 || set1->fixed)
return;
if (set1->op != OP_SET) {
- Instruction *xchg = set0;
+ BaseInstruction *xchg = set0;
set0 = set1;
set1 = xchg;
if (set1->op != OP_SET)
@@ -1902,7 +1907,7 @@ AlgebraicOpt::handleLOGOP(Instruction *logop)
if (set0->getDef(0)->refCount() > 1 &&
set1->getDef(0)->refCount() > 1)
return;
- if (set0->getPredicate() || set1->getPredicate())
+ if (asInsn(set0)->getPredicate() || asInsn(set1)->getPredicate())
return;
// check that they don't source each other
for (int s = 0; s < 2; ++s)
@@ -1918,7 +1923,7 @@ AlgebraicOpt::handleLOGOP(Instruction *logop)
set0->dType = TYPE_U8;
set0->getDef(0)->reg.file = FILE_PREDICATE;
set0->getDef(0)->reg.size = 1;
- set1->setSrc(2, set0->getDef(0));
+ asInsn(set1)->setSrc(2, set0->getDef(0));
set1->op = redOp;
set1->setDef(0, logop->getDef(0));
delete_Instruction(prog, logop);
@@ -1931,7 +1936,7 @@ AlgebraicOpt::handleLOGOP(Instruction *logop)
void
AlgebraicOpt::handleCVT_NEG(Instruction *cvt)
{
- Instruction *insn = cvt->getSrc(0)->getInsn();
+ BaseInstruction *insn = cvt->getSrc(0)->getInsn();
if (cvt->sType != TYPE_F32 ||
cvt->dType != TYPE_S32 || cvt->src(0).mod != Modifier(0))
return;
@@ -1957,7 +1962,7 @@ AlgebraicOpt::handleCVT_NEG(Instruction *cvt)
return;
}
- Instruction *bset = cloneShallow(func, insn);
+ Instruction *bset = asInsn(cloneShallow(func, insn));
bset->dType = TYPE_U32;
bset->setDef(0, cvt->getDef(0));
cvt->bb->insertAfter(cvt, bset);
@@ -1971,14 +1976,8 @@ AlgebraicOpt::handleCVT_NEG(Instruction *cvt)
void
AlgebraicOpt::handleCVT_CVT(Instruction *cvt)
{
- Instruction *insn = cvt->getSrc(0)->getInsn();
- RoundMode rnd = insn->rnd;
-
- if (insn->saturate ||
- insn->subOp ||
- insn->dType != insn->sType ||
- insn->dType != cvt->sType)
- return;
+ BaseInstruction *insn = cvt->getSrc(0)->getInsn();
+ RoundMode rnd;
switch (insn->op) {
case OP_CEIL:
@@ -1991,11 +1990,18 @@ AlgebraicOpt::handleCVT_CVT(Instruction *cvt)
rnd = ROUND_ZI;
break;
case OP_CVT:
+ rnd = asInsn(insn)->rnd;
break;
default:
return;
}
+ if (asInsn(insn)->saturate ||
+ asInsn(insn)->subOp ||
+ insn->dType != insn->sType ||
+ insn->dType != cvt->sType)
+ return;
+
if (!isFloatType(cvt->dType) || !isFloatType(insn->sType))
rnd = (RoundMode)(rnd & 3);
@@ -2016,7 +2022,7 @@ AlgebraicOpt::handleCVT_CVT(Instruction *cvt)
void
AlgebraicOpt::handleCVT_EXTBF(Instruction *cvt)
{
- Instruction *insn = cvt->getSrc(0)->getInsn();
+ BaseInstruction *insn = cvt->getSrc(0)->getInsn();
ImmediateValue imm;
Value *arg = NULL;
unsigned width, offset;
@@ -2050,7 +2056,7 @@ AlgebraicOpt::handleCVT_EXTBF(Instruction *cvt)
return;
arg = insn->getSrc(!s);
- Instruction *shift = arg->getInsn();
+ BaseInstruction *shift = arg->getInsn();
offset = 0;
if (shift && shift->op == OP_SHR &&
shift->sType == cvt->sType &&
@@ -2083,7 +2089,7 @@ AlgebraicOpt::handleCVT_EXTBF(Instruction *cvt)
// Irrespective of what came earlier, we can undo a shift on the argument
// by adjusting the offset.
- Instruction *shift = arg->getInsn();
+ BaseInstruction *shift = arg->getInsn();
if (shift && shift->op == OP_SHL &&
shift->src(1).getImmediate(imm) &&
((width == 8 && (imm.reg.data.u32 & 0x7) == 0) ||
@@ -2113,7 +2119,7 @@ AlgebraicOpt::handleSUCLAMP(Instruction *insn)
ImmediateValue imm;
int32_t val = insn->getSrc(2)->asImm()->reg.data.s32;
int s;
- Instruction *add;
+ BaseInstruction *add;
assert(insn->srcExists(0) && insn->src(0).getFile() == FILE_GPR);
@@ -2150,7 +2156,7 @@ AlgebraicOpt::handleSUCLAMP(Instruction *insn)
// NEG(AND(SET, 1)) -> SET
void
AlgebraicOpt::handleNEG(Instruction *i) {
- Instruction *src = i->getSrc(0)->getInsn();
+ BaseInstruction *src = i->getSrc(0)->getInsn();
ImmediateValue imm;
int b;
@@ -2167,7 +2173,7 @@ AlgebraicOpt::handleNEG(Instruction *i) {
if (!imm.isInteger(1))
return;
- Instruction *set = src->getSrc(b)->getInsn();
+ BaseInstruction *set = src->getSrc(b)->getInsn();
if ((set->op == OP_SET || set->op == OP_SET_AND ||
set->op == OP_SET_OR || set->op == OP_SET_XOR) &&
!isFloatType(set->dType)) {
@@ -2180,7 +2186,7 @@ AlgebraicOpt::visit(BasicBlock *bb)
{
Instruction *next;
for (Instruction *i = bb->getEntry(); i; i = next) {
- next = i->next;
+ next = i->getNext();
switch (i->op) {
case OP_ABS:
handleABS(i);
@@ -2272,7 +2278,7 @@ LateAlgebraicOpt::tryADDToSHLADD(Instruction *add)
return false;
src = add->getSrc(s);
- shl = src->getUniqueInsn();
+ shl = asInsn(src->getUniqueInsn());
if (shl->bb != add->bb || shl->usesFlags() || shl->subOp || shl->src(0).mod)
return false;
@@ -2326,7 +2332,7 @@ Split64BitOpPreRA::visit(BasicBlock *bb)
Modifier mod;
for (i = bb->getEntry(); i; i = next) {
- next = i->next;
+ next = i->getNext();
DataType hTy;
switch (i->dType) {
@@ -2908,7 +2914,7 @@ MemoryOpt::runOpt(BasicBlock *bb)
for (ldst = bb->getEntry(); ldst; ldst = next) {
bool keep = true;
bool isLoad = true;
- next = ldst->next;
+ next = ldst->getNext();
if (ldst->op == OP_LOAD || ldst->op == OP_VFETCH) {
if (ldst->isDead()) {
@@ -3012,7 +3018,7 @@ private:
void tryPropagateBranch(BasicBlock *);
inline bool isConstantCondition(Value *pred);
inline bool mayPredicate(const Instruction *, const Value *pred) const;
- inline void removeFlow(Instruction *);
+ inline void removeFlow(BaseInstruction *);
uint8_t gpr_unit;
};
@@ -3020,13 +3026,13 @@ private:
bool
FlatteningPass::isConstantCondition(Value *pred)
{
- Instruction *insn = pred->getUniqueInsn();
+ BaseInstruction *insn = pred->getUniqueInsn();
assert(insn);
if (insn->op != OP_SET || insn->srcExists(2))
return false;
for (int s = 0; s < 2 && insn->srcExists(s); ++s) {
- Instruction *ld = insn->getSrc(s)->getUniqueInsn();
+ BaseInstruction *ld = insn->getSrc(s)->getUniqueInsn();
DataFile file;
if (ld) {
if (ld->op != OP_MOV && ld->op != OP_LOAD)
@@ -3053,7 +3059,7 @@ FlatteningPass::isConstantCondition(Value *pred)
}
void
-FlatteningPass::removeFlow(Instruction *insn)
+FlatteningPass::removeFlow(BaseInstruction *insn)
{
FlowInstruction *term = insn ? insn->asFlow() : NULL;
if (!term)
@@ -3073,7 +3079,7 @@ FlatteningPass::removeFlow(Instruction *insn)
delete_Instruction(prog, term);
if (pred && pred->refCount() == 0) {
- Instruction *pSet = pred->getUniqueInsn();
+ BaseInstruction *pSet = pred->getUniqueInsn();
pred->join->reg.data.id = -1; // deallocate
if (pSet->isDead())
delete_Instruction(prog, pSet);
@@ -3083,7 +3089,7 @@ FlatteningPass::removeFlow(Instruction *insn)
void
FlatteningPass::predicateInstructions(BasicBlock *bb, Value *pred, CondCode cc)
{
- for (Instruction *i = bb->getEntry(); i; i = i->next) {
+ for (Instruction *i = bb->getEntry(); i; i = i->getNext()) {
if (i->isNop())
continue;
assert(!i->getPredicate());
@@ -3122,7 +3128,7 @@ FlatteningPass::mayPredicate(const Instruction *insn, const Value *pred) const
void
FlatteningPass::tryPropagateBranch(BasicBlock *bb)
{
- for (Instruction *i = bb->getExit(); i && i->op == OP_BRA; i = i->prev) {
+ for (BaseInstruction *i = bb->getExit(); i && i->op == OP_BRA; i = i->prev) {
BasicBlock *bf = i->asFlow()->target.bb;
if (bf->getInsnCount() != 1)
@@ -3165,10 +3171,11 @@ FlatteningPass::visit(BasicBlock *bb)
// try to attach join to previous instruction
if (prog->getTarget()->hasJoin) {
- Instruction *insn = bb->getExit();
- if (insn && insn->op == OP_JOIN && !insn->getPredicate()) {
+ BaseInstruction *insn = bb->getExit();
+ if (insn && insn->op == OP_JOIN && !asInsn(insn)->getPredicate()) {
insn = insn->prev;
- if (insn && !insn->getPredicate() &&
+ if (insn && !insn->isNop() &&
+ !asInsn(insn)->getPredicate() &&
!insn->asFlow() &&
insn->op != OP_DISCARD &&
insn->op != OP_TEXBAR &&
@@ -3177,8 +3184,7 @@ FlatteningPass::visit(BasicBlock *bb)
insn->op != OP_LINTERP && // probably just nve4
insn->op != OP_PINTERP && // probably just nve4
((insn->op != OP_LOAD && insn->op != OP_STORE && insn->op != OP_ATOM) ||
- (typeSizeof(insn->dType) <= 4 && !insn->src(0).isIndirect(0))) &&
- !insn->isNop()) {
+ (typeSizeof(insn->dType) <= 4 && !insn->src(0).isIndirect(0)))) {
insn->join = 1;
bb->remove(bb->getExit());
return true;
@@ -3203,8 +3209,8 @@ FlatteningPass::tryPredicateConditional(BasicBlock *bb)
if (!mask)
return false;
- assert(bb->getExit());
- Value *pred = bb->getExit()->getPredicate();
+ assert(asInsn(bb->getExit()));
+ Value *pred = asInsn(bb->getExit())->getPredicate();
assert(pred);
if (isConstantCondition(pred))
@@ -3214,7 +3220,7 @@ FlatteningPass::tryPredicateConditional(BasicBlock *bb)
if (mask & 1) {
bL = BasicBlock::get(ei.getNode());
- for (insn = bL->getEntry(); insn; insn = insn->next, ++nL)
+ for (insn = bL->getEntry(); insn; insn = insn->getNext(), ++nL)
if (!mayPredicate(insn, pred))
return false;
if (nL > limit)
@@ -3224,7 +3230,7 @@ FlatteningPass::tryPredicateConditional(BasicBlock *bb)
if (mask & 2) {
bR = BasicBlock::get(ei.getNode());
- for (insn = bR->getEntry(); insn; insn = insn->next, ++nR)
+ for (insn = bR->getEntry(); insn; insn = insn->getNext(), ++nR)
if (!mayPredicate(insn, pred))
return false;
if (nR > limit)
@@ -3232,9 +3238,9 @@ FlatteningPass::tryPredicateConditional(BasicBlock *bb)
}
if (bL)
- predicateInstructions(bL, pred, bb->getExit()->cc);
+ predicateInstructions(bL, pred, asInsn(bb->getExit())->cc);
if (bR)
- predicateInstructions(bR, pred, inverseCondCode(bb->getExit()->cc));
+ predicateInstructions(bR, pred, inverseCondCode(asInsn(bb->getExit())->cc));
if (bb->joinAt) {
bb->remove(bb->joinAt);
@@ -3268,7 +3274,7 @@ private:
};
static bool
-post_ra_dead(Instruction *i)
+post_ra_dead(BaseInstruction *i)
{
for (int d = 0; i->defExists(d); ++d)
if (i->getDef(d)->refCount())
@@ -3299,7 +3305,7 @@ PostRaLoadPropagation::handleMADforNV50(Instruction *i)
return;
Value *vtmp;
- Instruction *def = i->getSrc(1)->getInsn();
+ BaseInstruction *def = i->getSrc(1)->getInsn();
if (def && def->op == OP_SPLIT && typeSizeof(def->sType) == 4)
def = def->getSrc(0)->getInsn();
@@ -3367,7 +3373,7 @@ PostRaLoadPropagation::handleMADforNVC0(Instruction *i)
if (s == 1)
i->swapSources(0, 1);
- Instruction *imm = i->getSrc(1)->getInsn();
+ BaseInstruction *imm = i->getSrc(1)->getInsn();
i->setSrc(1, imm->getSrc(0));
if (post_ra_dead(imm))
delete_Instruction(prog, imm);
@@ -3399,7 +3405,7 @@ class LocalCSE : public Pass
private:
virtual bool visit(BasicBlock *);
- inline bool tryReplace(Instruction **, Instruction *);
+ inline bool tryReplace(BaseInstruction **, BaseInstruction *);
DLList ops[OP_LAST + 1];
};
@@ -3411,13 +3417,13 @@ private:
};
bool
-Instruction::isActionEqual(const Instruction *that) const
+BaseInstruction::isActionEqual(const BaseInstruction *that) const
{
if (this->op != that->op ||
this->dType != that->dType ||
this->sType != that->sType)
return false;
- if (this->cc != that->cc)
+ if (asInsn(this) && asInsn(this)->cc != asInsn(that)->cc)
return false;
if (this->asTex()) {
@@ -3432,29 +3438,30 @@ Instruction::isActionEqual(const Instruction *that) const
} else
if (this->asFlow()) {
return false;
- } else {
- if (this->ipa != that->ipa ||
- this->lanes != that->lanes ||
- this->perPatch != that->perPatch)
- return false;
- if (this->postFactor != that->postFactor)
- return false;
}
- if (this->subOp != that->subOp ||
- this->saturate != that->saturate ||
- this->rnd != that->rnd ||
- this->ftz != that->ftz ||
- this->dnz != that->dnz ||
- this->cache != that->cache ||
- this->mask != that->mask)
- return false;
+ if (asInsn(this)) {
+ const Instruction *insnA = asInsn(this);
+ const Instruction *insnB = asInsn(that);
+ if (insnA->ipa != insnB->ipa ||
+ insnA->lanes != insnB->lanes ||
+ insnA->perPatch != insnB->perPatch ||
+ insnA->postFactor != insnB->postFactor ||
+ insnA->subOp != insnB->subOp ||
+ insnA->saturate != insnB->saturate ||
+ insnA->rnd != insnB->rnd ||
+ insnA->ftz != insnB->ftz ||
+ insnA->dnz != insnB->dnz ||
+ insnA->cache != insnB->cache ||
+ insnA->mask != insnB->mask)
+ return false;
+ }
return true;
}
bool
-Instruction::isResultEqual(const Instruction *that) const
+BaseInstruction::isResultEqual(const BaseInstruction *that) const
{
unsigned int d, s;
@@ -3465,7 +3472,7 @@ Instruction::isResultEqual(const Instruction *that) const
if (!isActionEqual(that))
return false;
- if (this->predSrc != that->predSrc)
+ if (asInsn(this) && asInsn(this)->predSrc != asInsn(that)->predSrc)
return false;
for (d = 0; this->defExists(d); ++d) {
@@ -3506,13 +3513,14 @@ Instruction::isResultEqual(const Instruction *that) const
bool
GlobalCSE::visit(BasicBlock *bb)
{
- Instruction *phi, *next, *ik;
+ PhiInstruction *phi, *next;
+ BaseInstruction *ik;
int s;
// TODO: maybe do this with OP_UNION, too
- for (phi = bb->getPhi(); phi && phi->op == OP_PHI; phi = next) {
- next = phi->next;
+ for (phi = bb->getPhi(); phi; phi = next) {
+ next = asPhi(phi->next);
if (phi->getSrc(0)->refCount() > 1)
continue;
ik = phi->getSrc(0)->getInsn();
@@ -3543,12 +3551,12 @@ GlobalCSE::visit(BasicBlock *bb)
}
bool
-LocalCSE::tryReplace(Instruction **ptr, Instruction *i)
+LocalCSE::tryReplace(BaseInstruction **ptr, BaseInstruction *i)
{
- Instruction *old = *ptr;
+ BaseInstruction *old = *ptr;
// TODO: maybe relax this later (causes trouble with OP_UNION)
- if (i->isPredicated())
+ if (asInsn(i) && asInsn(i)->isPredicated())
return false;
if (!old->isResultEqual(i))
@@ -3567,7 +3575,7 @@ LocalCSE::visit(BasicBlock *bb)
unsigned int replaced;
do {
- Instruction *ir, *next;
+ BaseInstruction *ir, *next;
replaced = 0;
@@ -3595,7 +3603,7 @@ LocalCSE::visit(BasicBlock *bb)
if (src) {
for (Value::UseIterator it = src->uses.begin();
it != src->uses.end(); ++it) {
- Instruction *ik = (*it)->getInsn();
+ BaseInstruction *ik = (*it)->getInsn();
if (ik && ik->bb == ir->bb && ik->serial < ir->serial)
if (tryReplace(&ir, ik))
break;
@@ -3603,7 +3611,7 @@ LocalCSE::visit(BasicBlock *bb)
} else {
DLLIST_FOR_EACH(&ops[ir->op], iter)
{
- Instruction *ik = reinterpret_cast<Instruction *>(iter.get());
+ BaseInstruction *ik = reinterpret_cast<BaseInstruction *>(iter.get());
if (tryReplace(&ir, ik))
break;
}
@@ -3653,30 +3661,31 @@ DeadCodeElim::buryAll(Program *prog)
bool
DeadCodeElim::visit(BasicBlock *bb)
{
- Instruction *prev;
+ BaseInstruction *prev;
- for (Instruction *i = bb->getExit(); i; i = prev) {
+ for (BaseInstruction *i = bb->getExit(); i; i = prev) {
prev = i->prev;
if (i->isDead()) {
++deadCount;
delete_Instruction(prog, i);
} else
if (i->defExists(1) &&
- i->subOp == 0 &&
- (i->op == OP_VFETCH || i->op == OP_LOAD)) {
- checkSplitLoad(i);
+ (i->op == OP_VFETCH || i->op == OP_LOAD) &&
+ asInsn(i)->subOp == 0) {
+ checkSplitLoad(asInsn(i));
} else
if (i->defExists(0) && !i->getDef(0)->refCount()) {
if (i->op == OP_ATOM ||
i->op == OP_SUREDP ||
i->op == OP_SUREDB) {
i->setDef(0, NULL);
- if (i->op == OP_ATOM && i->subOp == NV50_IR_SUBOP_ATOM_EXCH) {
- i->cache = CACHE_CV;
- i->op = OP_STORE;
- i->subOp = 0;
+ if (i->op == OP_ATOM && asInsn(i)->subOp == NV50_IR_SUBOP_ATOM_EXCH) {
+ Instruction *insn = asInsn(i);
+ insn->cache = CACHE_CV;
+ insn->op = OP_STORE;
+ insn->subOp = 0;
}
- } else if (i->op == OP_LOAD && i->subOp == NV50_IR_SUBOP_LOAD_LOCKED) {
+ } else if (i->op == OP_LOAD && asInsn(i)->subOp == NV50_IR_SUBOP_LOAD_LOCKED) {
i->setDef(0, i->getDef(1));
i->setDef(1, NULL);
}
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_print.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_print.cpp
index cbb21f5f72..29e45b7ebf 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_print.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_print.cpp
@@ -531,10 +531,12 @@ int Symbol::print(char *buf, size_t size,
return pos;
}
-void Instruction::print() const
+void BaseInstruction::print() const
{
#define BUFSZ 512
+ const Instruction *i = asInsn(this);
+
const size_t size = BUFSZ;
char buf[BUFSZ];
@@ -546,21 +548,21 @@ void Instruction::print() const
if (join)
PRINT("join ");
- if (predSrc >= 0) {
+ if (i && i->predSrc >= 0) {
const size_t pre = pos;
- if (getSrc(predSrc)->reg.file == FILE_PREDICATE) {
- if (cc == CC_NOT_P)
+ if (getSrc(i->predSrc)->reg.file == FILE_PREDICATE) {
+ if (i->cc == CC_NOT_P)
PRINT("not");
} else {
- PRINT("%s", CondCodeStr[cc]);
+ PRINT("%s", CondCodeStr[i->cc]);
}
if (pos > pre)
SPACE();
- pos += getSrc(predSrc)->print(&buf[pos], BUFSZ - pos);
+ pos += getSrc(i->predSrc)->print(&buf[pos], BUFSZ - pos);
PRINT(" %s", colour[TXT_INSN]);
}
- if (saturate)
+ if (i && i->saturate)
PRINT("sat ");
if (asFlow()) {
@@ -582,66 +584,67 @@ void Instruction::print() const
} else {
PRINT("%s ", operationStr[op]);
if (op == OP_LINTERP || op == OP_PINTERP)
- PRINT("%s ", interpStr[ipa]);
+ PRINT("%s ", interpStr[i->ipa]);
switch (op) {
case OP_SUREDP:
case OP_SUREDB:
case OP_ATOM:
- if (subOp < ARRAY_SIZE(atomSubOpStr))
- PRINT("%s ", atomSubOpStr[subOp]);
+ if (i->subOp < ARRAY_SIZE(atomSubOpStr))
+ PRINT("%s ", atomSubOpStr[i->subOp]);
break;
case OP_LOAD:
case OP_STORE:
- if (subOp < ARRAY_SIZE(ldstSubOpStr))
- PRINT("%s ", ldstSubOpStr[subOp]);
+ if (i->subOp < ARRAY_SIZE(ldstSubOpStr))
+ PRINT("%s ", ldstSubOpStr[i->subOp]);
break;
case OP_SUBFM:
- if (subOp < ARRAY_SIZE(subfmOpStr))
- PRINT("%s ", subfmOpStr[subOp]);
+ if (i->subOp < ARRAY_SIZE(subfmOpStr))
+ PRINT("%s ", subfmOpStr[i->subOp]);
break;
case OP_SHFL:
- if (subOp < ARRAY_SIZE(shflOpStr))
- PRINT("%s ", shflOpStr[subOp]);
+ if (i->subOp < ARRAY_SIZE(shflOpStr))
+ PRINT("%s ", shflOpStr[i->subOp]);
break;
case OP_PIXLD:
- if (subOp < ARRAY_SIZE(pixldOpStr))
- PRINT("%s ", pixldOpStr[subOp]);
+ if (i->subOp < ARRAY_SIZE(pixldOpStr))
+ PRINT("%s ", pixldOpStr[i->subOp]);
break;
case OP_RCP:
case OP_RSQ:
- if (subOp < ARRAY_SIZE(rcprsqOpStr))
- PRINT("%s ", rcprsqOpStr[subOp]);
+ if (i->subOp < ARRAY_SIZE(rcprsqOpStr))
+ PRINT("%s ", rcprsqOpStr[i->subOp]);
break;
case OP_EMIT:
- if (subOp < ARRAY_SIZE(emitOpStr))
- PRINT("%s ", emitOpStr[subOp]);
+ if (i->subOp < ARRAY_SIZE(emitOpStr))
+ PRINT("%s ", emitOpStr[i->subOp]);
break;
case OP_CCTL:
- if (subOp < ARRAY_SIZE(cctlOpStr))
- PRINT("%s ", cctlOpStr[subOp]);
+ if (i->subOp < ARRAY_SIZE(cctlOpStr))
+ PRINT("%s ", cctlOpStr[i->subOp]);
break;
case OP_BAR:
- if (subOp < ARRAY_SIZE(barOpStr))
- PRINT("%s ", barOpStr[subOp]);
+ if (i->subOp < ARRAY_SIZE(barOpStr))
+ PRINT("%s ", barOpStr[i->subOp]);
break;
default:
- if (subOp)
- PRINT("(SUBOP:%u) ", subOp);
+ if (i->subOp)
+ PRINT("(SUBOP:%u) ", i->subOp);
break;
}
- if (perPatch)
+ if (i && i->perPatch)
PRINT("patch ");
if (asTex())
PRINT("%s %s$r%u $s%u %s", asTex()->tex.target.getName(),
colour[TXT_MEM], asTex()->tex.r, asTex()->tex.s,
colour[TXT_INSN]);
- if (postFactor)
- PRINT("x2^%i ", postFactor);
- PRINT("%s%s", dnz ? "dnz " : (ftz ? "ftz " : ""), DataTypeStr[dType]);
+ if (i && i->postFactor)
+ PRINT("x2^%i ", i->postFactor);
+ PRINT("%s%s", i ? (i->dnz ? "dnz " : (i->ftz ? "ftz " : "")) : "",
+ DataTypeStr[dType]);
}
- if (rnd != ROUND_N)
- PRINT(" %s", RoundModeStr[rnd]);
+ if (i && i->rnd != ROUND_N)
+ PRINT(" %s", RoundModeStr[i->rnd]);
if (defExists(1))
PRINT(" {");
@@ -662,7 +665,7 @@ void Instruction::print() const
PRINT(" %s%s", colour[TXT_INSN], DataTypeStr[sType]);
for (s = 0; srcExists(s); ++s) {
- if (s == predSrc || src(s).usedAsPtr)
+ if ((i && s == i->predSrc) || src(s).usedAsPtr)
continue;
const size_t pre = pos;
SPACE();
@@ -676,14 +679,14 @@ void Instruction::print() const
else
pos += getSrc(s)->print(&buf[pos], BUFSZ - pos, sType);
}
- if (exit)
+ if (i && i->exit)
PRINT("%s exit", colour[TXT_INSN]);
PRINT("%s", colour[TXT_DEFAULT]);
buf[MIN2(pos, BUFSZ - 1)] = 0;
- INFO("%s (%u)\n", buf, encSize);
+ INFO("%s (%u)\n", buf, i ? i->encSize : 0);
}
class PrintPass : public Pass
@@ -693,7 +696,7 @@ public:
virtual bool visit(Function *);
virtual bool visit(BasicBlock *);
- virtual bool visit(Instruction *);
+ virtual bool visit(BaseInstruction *);
private:
int serial;
@@ -759,7 +762,7 @@ PrintPass::visit(BasicBlock *bb)
}
bool
-PrintPass::visit(Instruction *insn)
+PrintPass::visit(BaseInstruction *insn)
{
if (omit_serial)
INFO(" ");
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp
index b660fec75c..26cbe20fb4 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp
@@ -260,10 +260,10 @@ private:
void insertConstraintMove(Instruction *, int s);
bool insertConstraintMoves();
- void condenseDefs(Instruction *);
+ void condenseDefs(BaseInstruction *);
void condenseSrcs(Instruction *, const int first, const int last);
- void addHazard(Instruction *i, const ValueRef *src);
+ void addHazard(BaseInstruction *i, const ValueRef *src);
void textureMask(TexInstruction *);
void addConstraint(Instruction *, int s, int n);
bool detectConflict(Instruction *, int s);
@@ -319,8 +319,8 @@ private:
int32_t stackSize;
int32_t stackBase;
- LValue *unspill(Instruction *usei, LValue *, Value *slot);
- void spill(Instruction *defi, Value *slot, LValue *);
+ LValue *unspill(BaseInstruction *usei, LValue *, Value *slot);
+ void spill(BaseInstruction *defi, Value *slot, LValue *);
};
void
@@ -328,7 +328,7 @@ RegAlloc::BuildIntervalsPass::addLiveRange(Value *val,
const BasicBlock *bb,
int end)
{
- Instruction *insn = val->getUniqueInsn();
+ BaseInstruction *insn = val->getUniqueInsn();
if (!insn)
insn = bb->getFirst();
@@ -362,14 +362,14 @@ RegAlloc::PhiMovesPass::needNewElseBlock(BasicBlock *b, BasicBlock *p)
}
struct PhiMapHash {
- size_t operator()(const std::pair<Instruction *, BasicBlock *>& val) const {
- return hash<Instruction*>()(val.first) * 31 +
+ size_t operator()(const std::pair<PhiInstruction *, BasicBlock *>& val) const {
+ return hash<PhiInstruction*>()(val.first) * 31 +
hash<BasicBlock*>()(val.second);
}
};
typedef unordered_map<
- std::pair<Instruction *, BasicBlock *>, Value *, PhiMapHash> PhiMap;
+ std::pair<PhiInstruction *, BasicBlock *>, Value *, PhiMapHash> PhiMap;
// Critical edges need to be split up so that work can be inserted along
// specific edge transitions. Unfortunately manipulating incident edges into a
@@ -382,7 +382,7 @@ void
RegAlloc::PhiMovesPass::splitEdges(BasicBlock *bb)
{
BasicBlock *pb, *pn;
- Instruction *phi;
+ PhiInstruction *phi;
Graph::EdgeIterator ei;
std::stack<BasicBlock *> stack;
int j = 0;
@@ -406,7 +406,7 @@ RegAlloc::PhiMovesPass::splitEdges(BasicBlock *bb)
j = 0;
for (ei = bb->cfg.incident(); !ei.end(); ei.next(), j++) {
pb = BasicBlock::get(ei.getNode());
- for (phi = bb->getPhi(); phi && phi->op == OP_PHI; phi = phi->next)
+ for (phi = bb->getPhi(); phi; phi = asPhi(phi->next))
phis.insert(std::make_pair(std::make_pair(phi, pb), phi->getSrc(j)));
}
@@ -423,7 +423,8 @@ RegAlloc::PhiMovesPass::splitEdges(BasicBlock *bb)
if (pb->getExit()->asFlow()->target.bb == bb)
pb->getExit()->asFlow()->target.bb = pn;
- for (phi = bb->getPhi(); phi && phi->op == OP_PHI; phi = phi->next) {
+
+ for (phi = bb->getPhi(); phi; phi = asPhi(phi->next)) {
PhiMap::iterator it = phis.find(std::make_pair(phi, pb));
assert(it != phis.end());
phis.insert(std::make_pair(std::make_pair(phi, pn), it->second));
@@ -435,7 +436,7 @@ RegAlloc::PhiMovesPass::splitEdges(BasicBlock *bb)
j = 0;
for (ei = bb->cfg.incident(); !ei.end(); ei.next(), j++) {
pb = BasicBlock::get(ei.getNode());
- for (phi = bb->getPhi(); phi && phi->op == OP_PHI; phi = phi->next) {
+ for (phi = bb->getPhi(); phi; phi = asPhi(phi->next)) {
PhiMap::const_iterator it = phis.find(std::make_pair(phi, pb));
assert(it != phis.end());
@@ -455,7 +456,8 @@ RegAlloc::PhiMovesPass::splitEdges(BasicBlock *bb)
bool
RegAlloc::PhiMovesPass::visit(BasicBlock *bb)
{
- Instruction *phi, *mov;
+ PhiInstruction *phi;
+ Instruction *mov;
splitEdges(bb);
@@ -466,7 +468,7 @@ RegAlloc::PhiMovesPass::visit(BasicBlock *bb)
if (!pb->isTerminated())
pb->insertTail(new_FlowInstruction(func, OP_BRA, bb));
- for (phi = bb->getPhi(); phi && phi->op == OP_PHI; phi = phi->next) {
+ for (phi = bb->getPhi(); phi; phi = asPhi(phi->next)) {
LValue *tmp = new_LValue(func, phi->getDef(0)->asLValue());
mov = new_Instruction(func, OP_MOV, typeOfSize(tmp->reg.size));
@@ -488,7 +490,7 @@ RegAlloc::ArgumentMovesPass::visit(BasicBlock *bb)
// Bind function call inputs/outputs to the same physical register
// the callee uses, inserting moves as appropriate for the case a
// conflict arises.
- for (Instruction *i = bb->getEntry(); i; i = i->next) {
+ for (Instruction *i = bb->getEntry(); i; i = i->getNext()) {
FlowInstruction *cal = i->asFlow();
// TODO: Handle indirect calls.
// Right now they should only be generated for builtins.
@@ -555,7 +557,7 @@ RegAlloc::buildLiveSets(BasicBlock *bb)
{
Function *f = bb->getFunction();
BasicBlock *bn;
- Instruction *i;
+ BaseInstruction *i;
unsigned int s, d;
INFO_DBG(prog->dbgFlags, REG_ALLOC, "buildLiveSets(BB:%i)\n", bb->getId());
@@ -651,7 +653,7 @@ RegAlloc::BuildIntervalsPass::visit(BasicBlock *bb)
for (Graph::EdgeIterator ei = bb->cfg.outgoing(); !ei.end(); ei.next()) {
BasicBlock *out = BasicBlock::get(ei.getNode());
- for (Instruction *i = out->getPhi(); i && i->op == OP_PHI; i = i->next) {
+ for (BaseInstruction *i = out->getPhi(); i && i->op == OP_PHI; i = i->next) {
bb->liveSet.clr(i->getDef(0)->id);
for (int s = 0; i->srcExists(s); ++s) {
@@ -671,7 +673,7 @@ RegAlloc::BuildIntervalsPass::visit(BasicBlock *bb)
addLiveRange(func->getLValue(j), bb, bb->getExit()->serial + 1);
}
- for (Instruction *i = bb->getExit(); i && i->op != OP_PHI; i = i->prev) {
+ for (BaseInstruction *i = bb->getExit(); i && i->op != OP_PHI; i = i->prev) {
for (int d = 0; i->defExists(d); ++d) {
bb->liveSet.clr(i->getDef(d)->id);
if (i->getDef(d)->reg.data.id >= 0) // add hazard for fixed regs
@@ -779,7 +781,7 @@ private:
bool coalesceValues(Value *, Value *, bool force);
void resolveSplitsAndMerges();
- void makeCompound(Instruction *, bool isSplit);
+ void makeCompound(BaseInstruction *, bool isSplit);
inline void checkInterference(const RIG_Node *, Graph::EdgeIterator&);
@@ -840,7 +842,7 @@ GCRA::printNodeInfo() const
}
static bool
-isShortRegOp(Instruction *insn)
+isShortRegOp(BaseInstruction *insn)
{
// Immediates are always in src1. Every other situation can be resolved by
// using a long encoding.
@@ -1017,7 +1019,7 @@ static inline void copyCompound(Value *dst, Value *src)
}
void
-GCRA::makeCompound(Instruction *insn, bool split)
+GCRA::makeCompound(BaseInstruction *insn, bool split)
{
LValue *rep = (split ? insn->getSrc(0) : insn->getDef(0))->asLValue();
@@ -1056,8 +1058,8 @@ GCRA::doCoalesce(ArrayList& insns, unsigned int mask)
int c, n;
for (n = 0; n < insns.getSize(); ++n) {
- Instruction *i;
- Instruction *insn = reinterpret_cast<Instruction *>(insns.get(n));
+ BaseInstruction *i;
+ BaseInstruction *insn = reinterpret_cast<BaseInstruction *>(insns.get(n));
switch (insn->op) {
case OP_PHI:
@@ -1077,7 +1079,7 @@ GCRA::doCoalesce(ArrayList& insns, unsigned int mask)
for (c = 0; insn->srcExists(c); ++c)
coalesceValues(insn->getDef(0), insn->getSrc(c), true);
if (insn->op == OP_MERGE) {
- merges.push_back(insn);
+ merges.push_back(asInsn(insn));
if (insn->srcExists(1))
makeCompound(insn, false);
}
@@ -1085,7 +1087,7 @@ GCRA::doCoalesce(ArrayList& insns, unsigned int mask)
case OP_SPLIT:
if (!(mask & JOIN_MASK_UNION))
break;
- splits.push_back(insn);
+ splits.push_back(asInsn(insn));
for (c = 0; insn->defExists(c); ++c)
coalesceValues(insn->getSrc(0), insn->getDef(c), true);
makeCompound(insn, true);
@@ -1117,7 +1119,7 @@ GCRA::doCoalesce(ArrayList& insns, unsigned int mask)
case OP_TEXPREP:
if (!(mask & JOIN_MASK_TEX))
break;
- for (c = 0; insn->srcExists(c) && c != insn->predSrc; ++c)
+ for (c = 0; insn->srcExists(c) && c != asInsn(insn)->predSrc; ++c)
coalesceValues(insn->getDef(c), insn->getSrc(c), true);
break;
default:
@@ -1468,7 +1470,7 @@ GCRA::allocateRegisters(ArrayList& insns)
RIG.insert(&nodes[i]);
if (lval->inFile(FILE_GPR) && lval->getInsn() != NULL) {
- Instruction *insn = lval->getInsn();
+ BaseInstruction *insn = lval->getInsn();
if (insn->op != OP_MAD && insn->op != OP_FMA && insn->op != OP_SAD)
continue;
// For both of the cases below, we only want to add the preference
@@ -1481,7 +1483,7 @@ GCRA::allocateRegisters(ArrayList& insns)
// Outputting a flag is not supported with short encodings nor
// with immediate arguments.
// See handleMADforNV50.
- if (insn->flagsDef >= 0)
+ if (asInsn(insn)->flagsDef >= 0)
continue;
} else {
// We can only fold immediate arguments if dst == src2. This
@@ -1635,7 +1637,7 @@ SpillCodeInserter::offsetSlot(Value *base, const LValue *lval)
}
void
-SpillCodeInserter::spill(Instruction *defi, Value *slot, LValue *lval)
+SpillCodeInserter::spill(BaseInstruction *defi, Value *slot, LValue *lval)
{
const DataType ty = typeOfSize(lval->reg.size);
@@ -1676,7 +1678,7 @@ SpillCodeInserter::spill(Instruction *defi, Value *slot, LValue *lval)
}
LValue *
-SpillCodeInserter::unspill(Instruction *usei, LValue *lval, Value *slot)
+SpillCodeInserter::unspill(BaseInstruction *usei, LValue *lval, Value *slot)
{
const DataType ty = typeOfSize(lval->reg.size);
@@ -1721,7 +1723,7 @@ SpillCodeInserter::unspill(Instruction *usei, LValue *lval, Value *slot)
static bool
value_cmp(ValueRef *a, ValueRef *b) {
- Instruction *ai = a->getInsn(), *bi = b->getInsn();
+ BaseInstruction *ai = a->getInsn(), *bi = b->getInsn();
if (ai->bb != bi->bb)
return ai->bb->getId() < bi->bb->getId();
return ai->serial < bi->serial;
@@ -1747,17 +1749,17 @@ SpillCodeInserter::run(const std::list<ValuePair>& lst)
// Keep track of which instructions to delete later. Deleting them
// inside the loop is unsafe since a single instruction may have
// multiple destinations that all need to be spilled (like OP_SPLIT).
- unordered_set<Instruction *> to_del;
+ unordered_set<BaseInstruction *> to_del;
for (Value::DefIterator d = lval->defs.begin(); d != lval->defs.end();
++d) {
Value *slot = mem ?
static_cast<Value *>(mem) : new_LValue(func, FILE_GPR);
Value *tmp = NULL;
- Instruction *last = NULL;
+ BaseInstruction *last = NULL;
LValue *dval = (*d)->get()->asLValue();
- Instruction *defi = (*d)->getInsn();
+ BaseInstruction *defi = (*d)->getInsn();
// Sort all the uses by BB/instruction so that we don't unspill
// multiple times in a row, and also remove a source of
@@ -1770,7 +1772,7 @@ SpillCodeInserter::run(const std::list<ValuePair>& lst)
for (std::vector<ValueRef*>::const_iterator it = refs.begin();
it != refs.end(); ++it) {
ValueRef *u = *it;
- Instruction *usei = u->getInsn();
+ BaseInstruction *usei = u->getInsn();
assert(usei);
if (usei->isPseudo()) {
tmp = (slot->reg.file == FILE_MEMORY_LOCAL) ? NULL : slot;
@@ -1796,7 +1798,7 @@ SpillCodeInserter::run(const std::list<ValuePair>& lst)
}
}
- for (unordered_set<Instruction *>::const_iterator it = to_del.begin();
+ for (unordered_set<BaseInstruction *>::const_iterator it = to_del.begin();
it != to_del.end(); ++it)
delete_Instruction(func->getProgram(), *it);
}
@@ -1922,7 +1924,7 @@ GCRA::resolveSplitsAndMerges()
// perform the same fixup on that node's sources, since after RA
// their registers should be identical.
if (v->getInsn()->op == OP_PHI || v->getInsn()->op == OP_UNION) {
- Instruction *phi = v->getInsn();
+ BaseInstruction *phi = v->getInsn();
for (int phis = 0; phi->srcExists(phis); ++phis) {
phi->getSrc(phis)->join = v;
phi->getSrc(phis)->reg.data.id = v->reg.data.id;
@@ -1993,7 +1995,7 @@ RegAlloc::InsertConstraintsPass::detectConflict(Instruction *cst, int s)
if (v == cst->getSrc(c))
return true;
- Instruction *defi = v->getInsn();
+ BaseInstruction *defi = v->getInsn();
return (!defi || defi->constrainedDefs());
}
@@ -2036,7 +2038,7 @@ RegAlloc::InsertConstraintsPass::addConstraint(Instruction *i, int s, int n)
// to prevent it from being assigned a register which overlapping the load's
// destination, which would produce random corruptions.
void
-RegAlloc::InsertConstraintsPass::addHazard(Instruction *i, const ValueRef *src)
+RegAlloc::InsertConstraintsPass::addHazard(BaseInstruction *i, const ValueRef *src)
{
Instruction *hzd = new_Instruction(func, OP_NOP, TYPE_NONE);
hzd->setSrc(0, src->get());
@@ -2046,7 +2048,7 @@ RegAlloc::InsertConstraintsPass::addHazard(Instruction *i, const ValueRef *src)
// b32 { %r0 %r1 %r2 %r3 } -> b128 %r0q
void
-RegAlloc::InsertConstraintsPass::condenseDefs(Instruction *insn)
+RegAlloc::InsertConstraintsPass::condenseDefs(BaseInstruction *insn)
{
uint8_t size = 0;
int n;
@@ -2070,7 +2072,8 @@ RegAlloc::InsertConstraintsPass::condenseDefs(Instruction *insn)
insn->setDef(d, NULL);
}
// carry over predicate if any (mainly for OP_UNION uses)
- split->setPredicate(insn->cc, insn->getPredicate());
+ if (asInsn(insn))
+ split->setPredicate(asInsn(insn)->cc, asInsn(insn)->getPredicate());
insn->bb->insertAfter(insn, split);
constrList.push_back(split);
@@ -2253,12 +2256,12 @@ bool
RegAlloc::InsertConstraintsPass::visit(BasicBlock *bb)
{
TexInstruction *tex;
- Instruction *next;
+ BaseInstruction *next;
int s, size;
targ = bb->getProgram()->getTarget();
- for (Instruction *i = bb->getEntry(); i; i = next) {
+ for (BaseInstruction *i = bb->getEntry(); i; i = next) {
next = i->next;
if ((tex = i->asTex())) {
@@ -2292,7 +2295,7 @@ RegAlloc::InsertConstraintsPass::visit(BasicBlock *bb)
assert(i->srcExists(s));
size -= i->getSrc(s)->reg.size;
}
- condenseSrcs(i, 1, s - 1);
+ condenseSrcs(asInsn(i), 1, s - 1);
} else
if (i->op == OP_LOAD || i->op == OP_VFETCH) {
condenseDefs(i);
@@ -2304,7 +2307,7 @@ RegAlloc::InsertConstraintsPass::visit(BasicBlock *bb)
if (i->op == OP_UNION ||
i->op == OP_MERGE ||
i->op == OP_SPLIT) {
- constrList.push_back(i);
+ constrList.push_back(asInsn(i));
}
}
return true;
@@ -2317,7 +2320,7 @@ RegAlloc::InsertConstraintsPass::insertConstraintMove(Instruction *cst, int s)
assert(cst->getSrc(s)->defs.size() == 1); // still SSA
- Instruction *defi = cst->getSrc(s)->defs.front()->getInsn();
+ BaseInstruction *defi = cst->getSrc(s)->defs.front()->getInsn();
bool imm = defi->op == OP_MOV &&
defi->src(0).getFile() == FILE_IMMEDIATE;
bool load = defi->op == OP_LOAD &&
@@ -2348,8 +2351,8 @@ RegAlloc::InsertConstraintsPass::insertConstraintMove(Instruction *cst, int s)
mov->setSrc(0, defi->getSrc(0));
}
- if (defi->getPredicate())
- mov->setPredicate(defi->cc, defi->getPredicate());
+ if (asInsn(defi) && asInsn(defi)->getPredicate())
+ mov->setPredicate(asInsn(defi)->cc, asInsn(defi)->getPredicate());
cst->setSrc(s, mov->getDef(0));
cst->bb->insertBefore(cst, mov);
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_ssa.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_ssa.cpp
index 3d25ad928e..e2f7522c74 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_ssa.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_ssa.cpp
@@ -242,7 +242,7 @@ Function::buildLiveSetsPreSSA(BasicBlock *bb, const int seq)
bb->liveSet.fill(0);
bb->liveSet.marker = true;
- for (Instruction *i = bb->getEntry(); i; i = i->next) {
+ for (BaseInstruction *i = bb->getEntry(); i; i = i->next) {
for (int s = 0; i->srcExists(s); ++s)
if (i->getSrc(s)->asLValue() && !assigned.test(i->getSrc(s)->id))
usedBeforeAssigned.set(i->getSrc(s)->id);
@@ -277,7 +277,7 @@ Function::buildDefSetsPreSSA(BasicBlock *bb, const int seq)
bb->defSet |= in->defSet;
}
- for (Instruction *i = bb->getEntry(); i; i = i->next) {
+ for (BaseInstruction *i = bb->getEntry(); i; i = i->next) {
for (int d = 0; i->defExists(d); ++d)
bb->defSet.set(i->getDef(d)->id);
}
@@ -371,7 +371,7 @@ Function::convertToSSA()
DLList::Iterator dfIter = bb->getDF().iterator();
for (; !dfIter.end(); dfIter.next()) {
- Instruction *phi;
+ PhiInstruction *phi;
BasicBlock *dfBB = BasicBlock::get(dfIter);
if (hasAlready[dfBB->getId()] >= iterCount)
@@ -382,12 +382,12 @@ Function::convertToSSA()
if (!dfBB->liveSet.test(lval->id))
continue;
- phi = new_Instruction(this, OP_PHI, typeOfSize(lval->reg.size));
+ phi = new_PhiInstruction(this, typeOfSize(lval->reg.size));
dfBB->insertTail(phi);
phi->setDef(0, lval);
- for (int s = 0; s < dfBB->cfg.incidentCount(); ++s)
- phi->setSrc(s, lval);
+ for (Graph::EdgeIterator ei = dfBB->cfg.incident(); !ei.end(); ei.next())
+ phi->setSrc(phi->srcCount(), lval);
if (work[dfBB->getId()] < iterCount) {
work[dfBB->getId()] = iterCount;
@@ -472,7 +472,7 @@ void RenamePass::search(BasicBlock *bb)
}
}
- for (Instruction *stmt = bb->getFirst(); stmt; stmt = stmt->next) {
+ for (BaseInstruction *stmt = bb->getFirst(); stmt; stmt = stmt->next) {
// PHI sources get definitions from the passes through the incident BBs,
// so skip them here.
if (stmt->op != OP_PHI) {
@@ -485,7 +485,7 @@ void RenamePass::search(BasicBlock *bb)
lval = getStackTop(lval);
if (!lval)
lval = mkUndefined(stmt->getSrc(s));
- stmt->setSrc(s, lval);
+ asInsn(stmt)->setSrc(s, lval);
}
}
for (d = 0; stmt->defExists(d); ++d) {
@@ -501,7 +501,7 @@ void RenamePass::search(BasicBlock *bb)
// Update sources of PHI ops corresponding to this BB in outgoing BBs.
for (Graph::EdgeIterator ei = bb->cfg.outgoing(); !ei.end(); ei.next()) {
- Instruction *phi;
+ PhiInstruction *phi;
int p = 0;
BasicBlock *sb = BasicBlock::get(ei.getNode());
@@ -513,7 +513,7 @@ void RenamePass::search(BasicBlock *bb)
}
assert(p < sb->cfg.incidentCount());
- for (phi = sb->getPhi(); phi && phi->op == OP_PHI; phi = phi->next) {
+ for (phi = sb->getPhi(); phi; phi = asPhi(phi->next)) {
lval = getStackTop(phi->getSrc(p));
if (!lval)
lval = mkUndefined(phi->getSrc(p));
@@ -542,7 +542,7 @@ void RenamePass::search(BasicBlock *bb)
// Pop the values we created in this block from the stack because we will
// return to blocks that we do not dominate.
- for (Instruction *stmt = bb->getFirst(); stmt; stmt = stmt->next) {
+ for (BaseInstruction *stmt = bb->getFirst(); stmt; stmt = stmt->next) {
if (stmt->op == OP_NOP)
continue;
for (d = 0; stmt->defExists(d); ++d)
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_target.cpp
index 298e7c6ef9..0135e720bc 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target.cpp
@@ -262,7 +262,7 @@ CodeEmitter::prepareEmission(BasicBlock *bb)
for (; j >= 0; --j) {
BasicBlock *in = func->bbArray[j];
- Instruction *exit = in->getExit();
+ BaseInstruction *exit = in->getExit();
if (exit && exit->op == OP_BRA && exit->asFlow()->target.bb == bb) {
in->binSize -= 8;
@@ -285,7 +285,7 @@ CodeEmitter::prepareEmission(BasicBlock *bb)
// determine encoding size, try to group short instructions
nShort = 0;
for (i = bb->getEntry(); i; i = next) {
- next = i->next;
+ next = i->getNext();
if (i->op == OP_MEMBAR && !targ->isOpSupported(OP_MEMBAR, TYPE_NONE)) {
bb->remove(i);
@@ -297,29 +297,29 @@ CodeEmitter::prepareEmission(BasicBlock *bb)
++nShort;
else
if ((nShort & 1) && next && getMinEncodingSize(next) == 4) {
- if (i->isCommutationLegal(i->next)) {
+ if (i->isCommutationLegal(i->getNext())) {
bb->permuteAdjacent(i, next);
next->encSize = 4;
next = i;
- i = i->prev;
+ i = i->getPrev();
++nShort;
} else
- if (i->isCommutationLegal(i->prev) && next->next) {
- bb->permuteAdjacent(i->prev, i);
+ if (i->isCommutationLegal(i->getPrev()) && next->getNext()) {
+ bb->permuteAdjacent(i->getPrev(), i);
next->encSize = 4;
- next = next->next;
+ next = next->getNext();
bb->binSize += 4;
++nShort;
} else {
i->encSize = 8;
- i->prev->encSize = 8;
+ i->getPrev()->encSize = 8;
bb->binSize += 4;
nShort = 0;
}
} else {
i->encSize = 8;
if (nShort & 1) {
- i->prev->encSize = 8;
+ i->getPrev()->encSize = 8;
bb->binSize += 4;
}
nShort = 0;
@@ -327,17 +327,17 @@ CodeEmitter::prepareEmission(BasicBlock *bb)
bb->binSize += i->encSize;
}
- if (bb->getExit()->encSize == 4) {
+ if (asInsn(bb->getExit())->encSize == 4) {
assert(nShort);
- bb->getExit()->encSize = 8;
+ asInsn(bb->getExit())->encSize = 8;
bb->binSize += 4;
- if ((bb->getExit()->prev->encSize == 4) && !(nShort & 1)) {
+ if ((asInsn(bb->getExit()->prev)->encSize == 4) && !(nShort & 1)) {
bb->binSize += 8;
- bb->getExit()->prev->encSize = 8;
+ asInsn(bb->getExit()->prev)->encSize = 8;
}
}
- assert(!bb->getEntry() || (bb->getExit() && bb->getExit()->encSize == 8));
+ assert(!bb->getEntry() || (bb->getExit() && asInsn(bb->getExit())->encSize == 8));
func->binSize += bb->binSize;
}
@@ -389,7 +389,7 @@ Program::emitBinary(struct nv50_ir_prog_info *info)
assert(emit->getCodeSize() == fn->binPos);
for (int b = 0; b < fn->bbCount; ++b) {
- for (Instruction *i = fn->bbArray[b]->getEntry(); i; i = i->next) {
+ for (Instruction *i = fn->bbArray[b]->getEntry(); i; i = i->getNext()) {
emit->emitInstruction(i);
info->bin.instructions++;
if ((typeSizeof(i->sType) == 8 || typeSizeof(i->dType) == 8) &&
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_util.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_util.h
index c619499046..732ad436ad 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_util.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_util.h
@@ -64,6 +64,8 @@
NV50_IR_FUNC_ALLOC_OBJ_DEF(TexInstruction, f, args)
#define new_FlowInstruction(f, args...) \
NV50_IR_FUNC_ALLOC_OBJ_DEF(FlowInstruction, f, args)
+#define new_PhiInstruction(f, args...) \
+ NV50_IR_FUNC_ALLOC_OBJ_DEF(PhiInstruction, f, args)
#define new_LValue(f, args...) \
NV50_IR_FUNC_ALLOC_OBJ_DEF(LValue, f, args)
--
2.14.4
More information about the mesa-dev
mailing list