[Beignet] [PATCH V2] GBE: optimize phi elimination.

Yang, Rong R rong.r.yang at intel.com
Tue Jul 14 01:57:55 PDT 2015


LGTM, will push it later, thanks.

> -----Original Message-----
> From: Beignet [mailto:beignet-bounces at lists.freedesktop.org] On Behalf Of
> Ruiling Song
> Sent: Monday, July 6, 2015 14:40
> To: beignet at lists.freedesktop.org
> Cc: Song, Ruiling
> Subject: [Beignet] [PATCH V2] GBE: optimize phi elimination.
> 
> This is special optimization for below situation:
> 
> bb1:
>     ...
> bb2:
>     x = phi [x1, bb1], [x2, bb2]
>     x2 = x+1;
> after de-ssa:
> bb2:
>     mov x, x-copy
>     add x2, x, 1
>     mov x-copy, x2
> obviously x2, x-copy and x2 can be mapped to same virtual register.
> 
> v2:
> only coaleasce if the source register comes from insn def.
> add check "if (phiDef->empty()) continue;" to skip no-def phiDef.
> 
> Signed-off-by: Ruiling Song <ruiling.song at intel.com>
> ---
>  backend/src/llvm/llvm_gen_backend.cpp | 70
> ++++++++++++++++++++++++++++++++++-
>  1 file changed, 68 insertions(+), 2 deletions(-)
> 
> diff --git a/backend/src/llvm/llvm_gen_backend.cpp
> b/backend/src/llvm/llvm_gen_backend.cpp
> index 37c9e7b..0ec113d 100644
> --- a/backend/src/llvm/llvm_gen_backend.cpp
> +++ b/backend/src/llvm/llvm_gen_backend.cpp
> @@ -2156,6 +2156,9 @@ namespace gbe
>      // between phi and phiCopy live range. If there is no point that
>      // phi & phiCopy are both alive, then we can optimize off the move
>      // from phiCopy to phi, and use phiCopy directly instead of phi.
> +    // right now, the algorithm is still very conservative, we need to do
> +    // aggressive coaleasing for the moves added during phi elimination.
> +
>      using namespace ir;
>      ir::FunctionDAG *dag = new ir::FunctionDAG(liveness);
> 
> @@ -2167,6 +2170,13 @@ namespace gbe
>        const ir::UseSet *phiUse = dag->getRegUse(phi);
>        const DefSet *phiDef = dag->getRegDef(phi);
>        bool isOpt = true;
> +
> +      // FIXME, I find under some situation, the phiDef maybe null, seems a
> bug when building FunctionDAg.
> +      // need fix it there.
> +      if (phiDef->empty()) continue;
> +
> +      const ir::BasicBlock *phiDefBB =
> + (*phiDef->begin())->getInstruction()->getParent();
> +
>        for (auto &x : *phiCopyDef) {
>          const ir::Instruction * phiCopyDefInsn = x->getInstruction();
>          const ir::BasicBlock *bb = phiCopyDefInsn->getParent(); @@ -2177,6
> +2187,63 @@ namespace gbe
>            isOpt = false;
>            break;
>          }
> +
> +        const ir::Register phiCopySrc = phiCopyDefInsn->getSrc(0);
> +        const ir::UseSet *phiCopySrcUse = dag->getRegUse(phiCopySrc);
> +        const ir::DefSet *phiCopySrcDef = dag->getRegDef(phiCopySrc);
> +        // non-ssa value. skip opt on such kind of value
> +        if (phiCopySrcDef->size() > 1) break;
> +        // we can only coalesce instruction dest
> +        if ((*(phiCopySrcDef->begin()))->getType() !=
> + ValueDef::DEF_INSN_DST) break;
> +
> +        const ir::Instruction *phiCopySrcDefInsn = (*(phiCopySrcDef-
> >begin()))->getInstruction();
> +        if(bb == phiDefBB && bb == phiCopySrcDefInsn->getParent()) {
> +          // phiCopy, phiCopySrc defined in same basicblock as phi
> +          // try to coalease phiCopy and phiCopySrc first.
> +          // consider below situation:
> +          // bb1:
> +          //    ...
> +          // bb2:
> +          //    x = phi [x1, bb1], [x2, bb2]
> +          //    x2 = x+1;
> +          // after de-ssa:
> +          // bb2:
> +          //    mov x, x-copy
> +          //    add x2, x, 1
> +          //    mov x-copy, x2
> +          //  obviously x2, x-copy and x2 can be mapped to same virtual
> + register
> +
> +          ir::BasicBlock::const_iterator iter =
> ir::BasicBlock::const_iterator(phiCopySrcDefInsn);
> +          ir::BasicBlock::const_iterator iterE = bb->end();
> +          // check no use of phi in this basicblock between [phiCopySrc def, bb
> end]
> +          bool phiPhiCopySrcInterfere = false;
> +          while (iter != iterE) {
> +            const ir::Instruction *insn = iter.node();
> +            // check phiUse
> +            for (unsigned i = 0; i < insn->getSrcNum(); i++) {
> +              ir::Register src = insn->getSrc(i);
> +              if (src == phi) {
> +                phiPhiCopySrcInterfere = true; break;
> +              }
> +            }
> +            ++iter;
> +          }
> +          if (!phiPhiCopySrcInterfere) {
> +            // phiCopy source can be coaleased with phiCopy
> +            const_cast<Instruction *>(phiCopyDefInsn)->remove();
> +
> +            for (auto &s : *phiCopySrcDef) {
> +              const Instruction *phiSrcDefInsn = s->getInstruction();
> +              replaceDst(const_cast<Instruction *>(phiSrcDefInsn), phiCopySrc,
> phiCopy);
> +            }
> +
> +            for (auto &s : *phiCopySrcUse) {
> +              const Instruction *phiSrcUseInsn = s->getInstruction();
> +              replaceSrc(const_cast<Instruction *>(phiSrcUseInsn), phiCopySrc,
> phiCopy);
> +            }
> +          }
> +        }
> +
>          // If phi is used in the same BB that define the phiCopy,
>          // we need carefully check the liveness of phi & phiCopy.
>          // Make sure their live ranges do not interfere.
> @@ -2206,8 +2273,7 @@ namespace gbe
>          }
>        }
> 
> -      // [MOV phi, phiCopy;] can be removed. So we remove it
> -      // and replace phi uses with phiCopy
> +      // coalease phi and phiCopy
>        if (isOpt) {
>          for (auto &x : *phiDef) {
>            const_cast<Instruction *>(x->getInstruction())->remove();
> --
> 2.3.6
> 
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list