diff options
author | Ruiling Song <ruiling.song@intel.com> | 2015-01-27 16:38:24 +0800 |
---|---|---|
committer | Zhigang Gong <zhigang.gong@intel.com> | 2015-02-11 16:31:08 +0800 |
commit | 26f1dbeb61cdd10dc53ae2767d48d0ab17d65793 (patch) | |
tree | 3f4092c768209da87848d6b7ac993c6cf1df9ae2 | |
parent | c960637ebe7d68c37fe299c63e74c0e269a9fdb3 (diff) |
GBE: Import constantexpr lower pass from pNaCl
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@intel.com>
-rw-r--r-- | backend/src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | backend/src/ir/immediate.hpp | 3 | ||||
-rw-r--r-- | backend/src/llvm/ExpandConstantExpr.cpp | 147 | ||||
-rw-r--r-- | backend/src/llvm/ExpandUtils.cpp | 117 | ||||
-rw-r--r-- | backend/src/llvm/llvm_gen_backend.cpp | 23 | ||||
-rw-r--r-- | backend/src/llvm/llvm_gen_backend.hpp | 15 | ||||
-rw-r--r-- | backend/src/llvm/llvm_to_gen.cpp | 7 |
7 files changed, 299 insertions, 15 deletions
diff --git a/backend/src/CMakeLists.txt b/backend/src/CMakeLists.txt index ce83c62f..907d8a3f 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 756806b8..10bd0352 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 00000000..54b8b16d --- /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 00000000..e6dfb523 --- /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 d547c71f..5eed85e5 100644 --- a/backend/src/llvm/llvm_gen_backend.cpp +++ b/backend/src/llvm/llvm_gen_backend.cpp @@ -2477,12 +2477,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 @@ -2525,12 +2525,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 e127996f..2bd070d5 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 e3b38229..f467edfb 100644 --- a/backend/src/llvm/llvm_to_gen.cpp +++ b/backend/src/llvm/llvm_to_gen.cpp @@ -268,15 +268,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 |