summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/nv50/codegen/nv50_ir.cpp39
-rw-r--r--src/gallium/drivers/nv50/codegen/nv50_ir.h7
-rw-r--r--src/gallium/drivers/nv50/codegen/nv50_ir_bb.cpp20
3 files changed, 66 insertions, 0 deletions
diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir.cpp
index 86e3d1c95af..8e7fc31eced 100644
--- a/src/gallium/drivers/nv50/codegen/nv50_ir.cpp
+++ b/src/gallium/drivers/nv50/codegen/nv50_ir.cpp
@@ -328,6 +328,21 @@ ImmediateValue::ImmediateValue(const ImmediateValue *proto, DataType ty)
reg.size = typeSizeof(ty);
}
+ImmediateValue *
+ImmediateValue::clone(ClonePolicy<Function>& pol) const
+{
+ Program *prog = pol.context()->getProgram();
+ ImmediateValue *that = new_ImmediateValue(prog, 0u);
+
+ pol.set<Value>(this, that);
+
+ that->reg.size = this->reg.size;
+ that->reg.type = this->reg.type;
+ that->reg.data = this->reg.data;
+
+ return that;
+}
+
bool
ImmediateValue::isInteger(const int i) const
{
@@ -853,6 +868,30 @@ FlowInstruction::FlowInstruction(Function *fn, operation op,
allWarp = absolute = limit = 0;
}
+FlowInstruction *
+FlowInstruction::clone(ClonePolicy<Function>& pol, Instruction *i) const
+{
+ FlowInstruction *flow = (i ? static_cast<FlowInstruction *>(i) :
+ new_FlowInstruction(pol.context(), op, NULL));
+
+ Instruction::clone(pol, flow);
+ flow->allWarp = allWarp;
+ flow->absolute = absolute;
+ flow->limit = limit;
+ flow->builtin = builtin;
+
+ if (builtin)
+ flow->target.builtin = target.builtin;
+ else
+ if (op == OP_CALL)
+ flow->target.fn = target.fn;
+ else
+ if (target.bb)
+ flow->target.bb = pol.get<BasicBlock>(target.bb);
+
+ return flow;
+}
+
Program::Program(Type type, Target *arch)
: progType(type),
target(arch),
diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir.h b/src/gallium/drivers/nv50/codegen/nv50_ir.h
index b5cf4b89a93..3f063b0ae29 100644
--- a/src/gallium/drivers/nv50/codegen/nv50_ir.h
+++ b/src/gallium/drivers/nv50/codegen/nv50_ir.h
@@ -550,6 +550,8 @@ public:
ImmediateValue(const ImmediateValue *, DataType ty);
~ImmediateValue() { };
+ virtual ImmediateValue *clone(ClonePolicy<Function>&) const;
+
virtual bool equals(const Value *that, bool strict) const;
// these only work if 'type' is valid (we mostly use untyped literals):
@@ -812,6 +814,9 @@ class FlowInstruction : public Instruction
public:
FlowInstruction(Function *, operation, BasicBlock *target);
+ virtual FlowInstruction *clone(ClonePolicy<Function>&,
+ Instruction * = NULL) const;
+
public:
unsigned allWarp : 1;
unsigned absolute : 1;
@@ -831,6 +836,8 @@ public:
BasicBlock(Function *);
~BasicBlock();
+ BasicBlock *clone(ClonePolicy<Function>&) const;
+
inline int getId() const { return id; }
inline unsigned int getInsnCount() const { return numInsns; }
inline bool isTerminated() const { return exit && exit->terminator; }
diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_bb.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir_bb.cpp
index e6f3c353a1b..07d8decee54 100644
--- a/src/gallium/drivers/nv50/codegen/nv50_ir_bb.cpp
+++ b/src/gallium/drivers/nv50/codegen/nv50_ir_bb.cpp
@@ -81,6 +81,26 @@ BasicBlock::~BasicBlock()
}
BasicBlock *
+BasicBlock::clone(ClonePolicy<Function>& pol) const
+{
+ BasicBlock *bb = new BasicBlock(pol.context());
+
+ pol.set(this, bb);
+
+ for (Instruction *i = getFirst(); i; i = i->next)
+ bb->insertTail(i->clone(pol));
+
+ pol.context()->cfg.insert(&bb->cfg);
+
+ for (Graph::EdgeIterator it = cfg.outgoing(); !it.end(); it.next()) {
+ BasicBlock *obb = BasicBlock::get(it.getNode());
+ bb->cfg.attach(&pol.get(obb)->cfg, it.getType());
+ }
+
+ return bb;
+}
+
+BasicBlock *
BasicBlock::idom() const
{
Graph::Node *dn = dom.parent();