[Beignet] [PATCH 1/2] GBE: Import constantexpr lower pass from pNaCl

Zhigang Gong zhigang.gong at linux.intel.com
Mon Feb 2 22:37:09 PST 2015


Nice patch, now we can simplify the constant expression handling code
in gen writer pass.

Thanks.

On Tue, Jan 27, 2015 at 04:38:24PM +0800, Ruiling Song wrote:
> The idea is lower the constantExpr into an Instruction.
> 
> Fix the ptrtoInt and IntToPtr implementation, it simply maps to
> a convert if type size not the same.
> 
> Fix a bitcast from integer to float issue. As we expand llvm::ConstantExpr
> into llvm::Instruction. We will meet below situation.
>   %10 = bitcast i32 1073741824 to float
>   %11 = fcmp float %10 0.000000e+00
> This will translated into GenIR:
>   %100 = loadi S32 1073741824
>   %101 = fcmp %100, 0.0f
> In later instruction selection, we may directly getFloat() from %100
> 
> Signed-off-by: Ruiling Song <ruiling.song at intel.com>
> ---
>  backend/src/CMakeLists.txt              |    2 +
>  backend/src/ir/immediate.hpp            |    3 +-
>  backend/src/llvm/ExpandConstantExpr.cpp |  147 +++++++++++++++++++++++++++++++
>  backend/src/llvm/ExpandUtils.cpp        |  117 ++++++++++++++++++++++++
>  backend/src/llvm/llvm_gen_backend.cpp   |   23 ++---
>  backend/src/llvm/llvm_gen_backend.hpp   |   15 +++-
>  backend/src/llvm/llvm_to_gen.cpp        |    7 +-
>  7 files changed, 299 insertions(+), 15 deletions(-)
>  create mode 100644 backend/src/llvm/ExpandConstantExpr.cpp
>  create mode 100644 backend/src/llvm/ExpandUtils.cpp
> 
> diff --git a/backend/src/CMakeLists.txt b/backend/src/CMakeLists.txt
> index ce83c62..907d8a3 100644
> --- a/backend/src/CMakeLists.txt
> +++ b/backend/src/CMakeLists.txt
> @@ -84,6 +84,8 @@ set (GBE_SRC
>      llvm/llvm_intrinsic_lowering.cpp
>      llvm/llvm_barrier_nodup.cpp
>      llvm/llvm_printf_parser.cpp
> +    llvm/ExpandConstantExpr.cpp
> +    llvm/ExpandUtils.cpp
>      llvm/llvm_to_gen.cpp
>      llvm/llvm_loadstore_optimization.cpp
>      llvm/llvm_gen_backend.hpp
> diff --git a/backend/src/ir/immediate.hpp b/backend/src/ir/immediate.hpp
> index 756806b..10bd035 100644
> --- a/backend/src/ir/immediate.hpp
> +++ b/backend/src/ir/immediate.hpp
> @@ -199,7 +199,8 @@ namespace ir {
>      }
>  
>      INLINE float getFloatValue(void) const {
> -      GBE_ASSERT(type == IMM_TYPE_FLOAT);
> +      // we allow bitcast from u32/s32 immediate to float
> +      GBE_ASSERT(type == IMM_TYPE_FLOAT || type == IMM_TYPE_U32 || type == IMM_TYPE_S32);
>        return *data.f32;
>      }
>  
> diff --git a/backend/src/llvm/ExpandConstantExpr.cpp b/backend/src/llvm/ExpandConstantExpr.cpp
> new file mode 100644
> index 0000000..54b8b16
> --- /dev/null
> +++ b/backend/src/llvm/ExpandConstantExpr.cpp
> @@ -0,0 +1,147 @@
> +/*
> + * Copyright © 2012 Intel Corporation
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library. If not, see <http://www.gnu.org/licenses/>.
> + *
> + */
> +
> +// Imported from pNaCl project
> +// Copyright (c) 2003-2014 University of Illinois at Urbana-Champaign.
> +// All rights reserved.
> +//
> +// Developed by:
> +//
> +//    LLVM Team
> +//
> +//    University of Illinois at Urbana-Champaign
> +//
> +//    http://llvm.org
> +//
> +// Permission is hereby granted, free of charge, to any person obtaining a copy of
> +// this software and associated documentation files (the "Software"), to deal with
> +// the Software without restriction, including without limitation the rights to
> +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
> +// of the Software, and to permit persons to whom the Software is furnished to do
> +// so, subject to the following conditions:
> +//
> +//    * Redistributions of source code must retain the above copyright notice,
> +//      this list of conditions and the following disclaimers.
> +//
> +//   * Redistributions in binary form must reproduce the above copyright notice,
> +//      this list of conditions and the following disclaimers in the
> +//      documentation and/or other materials provided with the distribution.
> +//
> +//    * Neither the names of the LLVM Team, University of Illinois at
> +//      Urbana-Champaign, nor the names of its contributors may be used to
> +//      endorse or promote products derived from this Software without specific
> +//      prior written permission.
> +//
> +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
> +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
> +// CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
> +// SOFTWARE.
> +
> +//===- ExpandConstantExpr.cpp - Convert ConstantExprs to Instructions------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// This pass expands out ConstantExprs into Instructions.
> +//
> +// Note that this only converts ConstantExprs that are referenced by
> +// Instructions.  It does not convert ConstantExprs that are used as
> +// initializers for global variables.
> +//
> +// This simplifies the language so that the PNaCl translator does not
> +// need to handle ConstantExprs as part of a stable wire format for
> +// PNaCl.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#include <map>
> +
> +#include "llvm/IR/Constants.h"
> +#include "llvm/IR/Function.h"
> +#include "llvm/IR/Instructions.h"
> +#include "llvm/Pass.h"
> +#include "llvm_gen_backend.hpp"
> +
> +using namespace llvm;
> +
> +static bool expandInstruction(Instruction *Inst);
> +
> +namespace {
> +  // This is a FunctionPass because our handling of PHI nodes means
> +  // that our modifications may cross BasicBlocks.
> +  struct ExpandConstantExpr : public FunctionPass {
> +    static char ID; // Pass identification, replacement for typeid
> +    ExpandConstantExpr() : FunctionPass(ID) {
> +    }
> +
> +    virtual bool runOnFunction(Function &Func);
> +  };
> +}
> +
> +char ExpandConstantExpr::ID = 0;
> +
> +static Value *expandConstantExpr(Instruction *InsertPt, ConstantExpr *Expr) {
> +  Instruction *NewInst = Expr->getAsInstruction();
> +  NewInst->insertBefore(InsertPt);
> +  NewInst->setName("expanded");
> +  expandInstruction(NewInst);
> +  return NewInst;
> +}
> +
> +static bool expandInstruction(Instruction *Inst) {
> +  // A landingpad can only accept ConstantExprs, so it should remain
> +  // unmodified.
> +  if (isa<LandingPadInst>(Inst))
> +    return false;
> +
> +  bool Modified = false;
> +  for (unsigned OpNum = 0; OpNum < Inst->getNumOperands(); OpNum++) {
> +    if (ConstantExpr *Expr =
> +        dyn_cast<ConstantExpr>(Inst->getOperand(OpNum))) {
> +      Modified = true;
> +      Use *U = &Inst->getOperandUse(OpNum);
> +      PhiSafeReplaceUses(U, expandConstantExpr(PhiSafeInsertPt(U), Expr));
> +    }
> +  }
> +  return Modified;
> +}
> +
> +bool ExpandConstantExpr::runOnFunction(Function &Func) {
> +  bool Modified = false;
> +  for (llvm::Function::iterator BB = Func.begin(), E = Func.end();
> +       BB != E;
> +       ++BB) {
> +    for (BasicBlock::InstListType::iterator Inst = BB->begin(), E = BB->end();
> +         Inst != E;
> +         ++Inst) {
> +      Modified |= expandInstruction(Inst);
> +    }
> +  }
> +  return Modified;
> +}
> +
> +FunctionPass *llvm::createExpandConstantExprPass() {
> +  return new ExpandConstantExpr();
> +}
> diff --git a/backend/src/llvm/ExpandUtils.cpp b/backend/src/llvm/ExpandUtils.cpp
> new file mode 100644
> index 0000000..e6dfb52
> --- /dev/null
> +++ b/backend/src/llvm/ExpandUtils.cpp
> @@ -0,0 +1,117 @@
> +/*
> + * Copyright © 2012 Intel Corporation
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library. If not, see <http://www.gnu.org/licenses/>.
> + *
> + */
> +
> +// Imported from pNaCl project
> +// Copyright (c) 2003-2014 University of Illinois at Urbana-Champaign.
> +// All rights reserved.
> +//
> +// Developed by:
> +//
> +//    LLVM Team
> +//
> +//    University of Illinois at Urbana-Champaign
> +//
> +//    http://llvm.org
> +//
> +// Permission is hereby granted, free of charge, to any person obtaining a copy of
> +// this software and associated documentation files (the "Software"), to deal with
> +// the Software without restriction, including without limitation the rights to
> +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
> +// of the Software, and to permit persons to whom the Software is furnished to do
> +// so, subject to the following conditions:
> +//
> +//    * Redistributions of source code must retain the above copyright notice,
> +//      this list of conditions and the following disclaimers.
> +//
> +//   * Redistributions in binary form must reproduce the above copyright notice,
> +//      this list of conditions and the following disclaimers in the
> +//      documentation and/or other materials provided with the distribution.
> +//
> +//    * Neither the names of the LLVM Team, University of Illinois at
> +//      Urbana-Champaign, nor the names of its contributors may be used to
> +//      endorse or promote products derived from this Software without specific
> +//      prior written permission.
> +//
> +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
> +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
> +// CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
> +// SOFTWARE.
> +
> +//===-- ExpandUtils.cpp - Helper functions for expansion passes -----------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm/IR/BasicBlock.h"
> +#include "llvm/IR/Constants.h"
> +#include "llvm/IR/Function.h"
> +#include "llvm/IR/Instructions.h"
> +#include "llvm/IR/Module.h"
> +#include "llvm/Support/raw_ostream.h"
> +#include "llvm_gen_backend.hpp"
> +
> +using namespace llvm;
> +namespace llvm {
> +
> +  Instruction *PhiSafeInsertPt(Use *U) {
> +    Instruction *InsertPt = cast<Instruction>(U->getUser());
> +    if (PHINode *PN = dyn_cast<PHINode>(InsertPt)) {
> +      // We cannot insert instructions before a PHI node, so insert
> +      // before the incoming block's terminator.  This could be
> +      // suboptimal if the terminator is a conditional.
> +      InsertPt = PN->getIncomingBlock(*U)->getTerminator();
> +    }
> +    return InsertPt;
> +  }
> +
> +  void PhiSafeReplaceUses(Use *U, Value *NewVal) {
> +    User *UR = U->getUser();
> +    if (PHINode *PN = dyn_cast<PHINode>(UR)) {
> +      // A PHI node can have multiple incoming edges from the same
> +      // block, in which case all these edges must have the same
> +      // incoming value.
> +      BasicBlock *BB = PN->getIncomingBlock(*U);
> +      for (unsigned I = 0; I < PN->getNumIncomingValues(); ++I) {
> +        if (PN->getIncomingBlock(I) == BB)
> +          PN->setIncomingValue(I, NewVal);
> +      }
> +    } else {
> +      UR->replaceUsesOfWith(U->get(), NewVal);
> +    }
> +  }
> +
> +  Function *RecreateFunction(Function *Func, FunctionType *NewType) {
> +    Function *NewFunc = Function::Create(NewType, Func->getLinkage());
> +    NewFunc->copyAttributesFrom(Func);
> +    Func->getParent()->getFunctionList().insert(Func, NewFunc);
> +    NewFunc->takeName(Func);
> +    NewFunc->getBasicBlockList().splice(NewFunc->begin(),
> +                                        Func->getBasicBlockList());
> +    Func->replaceAllUsesWith(
> +        ConstantExpr::getBitCast(NewFunc,
> +                                 Func->getFunctionType()->getPointerTo()));
> +    return NewFunc;
> +  }
> +}
> diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
> index 86030b9..0b1863f 100644
> --- a/backend/src/llvm/llvm_gen_backend.cpp
> +++ b/backend/src/llvm/llvm_gen_backend.cpp
> @@ -2480,12 +2480,12 @@ error:
>        case Instruction::PtrToInt:
>        case Instruction::IntToPtr:
>        {
> -        Constant *CPV = dyn_cast<Constant>(srcValue);
> -        if (CPV == NULL) {
> +        Type *dstType = dstValue->getType();
> +        Type *srcType = srcValue->getType();
> +
> +        if (getTypeByteSize(unit, dstType) == getTypeByteSize(unit, srcType))
> +        {
>  #if GBE_DEBUG
> -          Type *dstType = dstValue->getType();
> -          Type *srcType = srcValue->getType();
> -          GBE_ASSERT(getTypeByteSize(unit, dstType) == getTypeByteSize(unit, srcType));
>  #endif /* GBE_DEBUG */
>            regTranslator.newValueProxy(srcValue, dstValue);
>          } else
> @@ -2528,12 +2528,13 @@ error:
>        {
>          Value *dstValue = &I;
>          Value *srcValue = I.getOperand(0);
> -        Constant *CPV = dyn_cast<Constant>(srcValue);
> -        if (CPV != NULL) {
> -          const ir::ImmediateIndex index = ctx.newImmediate(CPV);
> -          const ir::Immediate imm = ctx.getImmediate(index);
> -          const ir::Register reg = this->getRegister(dstValue);
> -          ctx.LOADI(imm.getType(), reg, index);
> +        Type *dstType = dstValue->getType();
> +        Type *srcType = srcValue->getType();
> +
> +        if (getTypeByteSize(unit, dstType) != getTypeByteSize(unit, srcType)) {
> +          const ir::Register dst = this->getRegister(&I);
> +          const ir::Register src = this->getRegister(srcValue);
> +          ctx.CVT(getType(ctx, dstType), getType(ctx, srcType), dst, src);
>          }
>        }
>        break;
> diff --git a/backend/src/llvm/llvm_gen_backend.hpp b/backend/src/llvm/llvm_gen_backend.hpp
> index e127996..2bd070d 100644
> --- a/backend/src/llvm/llvm_gen_backend.hpp
> +++ b/backend/src/llvm/llvm_gen_backend.hpp
> @@ -40,7 +40,20 @@
>  #include <algorithm>
>  
>  // LLVM Type
> -namespace llvm { class Type; }
> +namespace llvm {
> +  class Type;
> +  /* Imported from pNaCl */
> +  llvm::Instruction *PhiSafeInsertPt(llvm::Use *U);
> +
> +  void PhiSafeReplaceUses(llvm::Use *U, llvm::Value *NewVal);
> +
> +  FunctionPass *createExpandConstantExprPass();
> +  // Copy debug information from Original to New, and return New.
> +  template <typename T> T *CopyDebug(T *New, llvm::Instruction *Original) {
> +    New->setDebugLoc(Original->getDebugLoc());
> +   return New;
> +  }
> +}
>  
>  namespace gbe
>  {
> diff --git a/backend/src/llvm/llvm_to_gen.cpp b/backend/src/llvm/llvm_to_gen.cpp
> index 1c247b8..6a37b4e 100644
> --- a/backend/src/llvm/llvm_to_gen.cpp
> +++ b/backend/src/llvm/llvm_to_gen.cpp
> @@ -269,15 +269,18 @@ namespace gbe
>      passes.add(createFunctionInliningPass(200000));
>      passes.add(createScalarReplAggregatesPass(64, true, -1, -1, 64));
>      passes.add(createLoadStoreOptimizationPass());
> -    passes.add(createRemoveGEPPass(unit));
>      passes.add(createConstantPropagationPass());
>      passes.add(createLowerSwitchPass());
>      passes.add(createPromoteMemoryToRegisterPass());
>      if(optLevel > 0)
>        passes.add(createGVNPass());                  // Remove redundancies
>      passes.add(createPrintfParserPass());
> +    passes.add(createExpandConstantExprPass());
>      passes.add(createScalarizePass());        // Expand all vector ops
> -    passes.add(createLegalizePass());
> +    passes.add(createLegalizePass());         // legalize large integer operation
> +    passes.add(createConstantPropagationPass()); // propagate constant after scalarize/legalize
> +    passes.add(createExpandConstantExprPass()); // constant prop may generate ConstantExpr
> +    passes.add(createRemoveGEPPass(unit)); // Constant prop may generate gep
>      passes.add(createDeadInstEliminationPass());  // Remove simplified instructions
>      passes.add(createCFGSimplificationPass());     // Merge & remove BBs
>      passes.add(createScalarizePass());        // Expand all vector ops
> -- 
> 1.7.10.4
> 
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list