nv50/ir: Add support for cloning FlowInsns, ImmediateVals and BBs.
authorFrancisco Jerez <currojerez@riseup.net>
Sat, 14 Apr 2012 19:25:22 +0000 (21:25 +0200)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Sat, 14 Apr 2012 19:54:01 +0000 (21:54 +0200)
src/gallium/drivers/nv50/codegen/nv50_ir.cpp
src/gallium/drivers/nv50/codegen/nv50_ir.h
src/gallium/drivers/nv50/codegen/nv50_ir_bb.cpp

index 86e3d1c..8e7fc31 100644 (file)
@@ -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),
index b5cf4b8..3f063b0 100644 (file)
@@ -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; }
index e6f3c35..07d8dec 100644 (file)
@@ -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();