diff options
-rw-r--r-- | src/gallium/drivers/nv50/codegen/nv50_ir.cpp | 39 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/codegen/nv50_ir.h | 7 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/codegen/nv50_ir_bb.cpp | 20 |
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(); |