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.s...@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@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/beignet _______________________________________________ Beignet mailing list Beignet@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/beignet