[Beignet] [PATCH 1/2] GBE: Import constantexpr lower pass from pNaCl
Ruiling Song
ruiling.song at intel.com
Tue Jan 27 00:38:24 PST 2015
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
More information about the Beignet
mailing list