[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