[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