[Beignet] [PATCH 03/19] Backend: Add ProfilingInserter and a new function pass.

Yang, Rong R rong.r.yang at intel.com
Tue Nov 3 04:39:38 PST 2015


One comment.

> -----Original Message-----
> From: Beignet [mailto:beignet-bounces at lists.freedesktop.org] On Behalf Of
> junyan.he at inbox.com
> Sent: Wednesday, September 9, 2015 8:01
> To: beignet at lists.freedesktop.org
> Subject: [Beignet] [PATCH 03/19] Backend: Add ProfilingInserter and a new
> function pass.
> 
> From: Junyan He <junyan.he at linux.intel.com>
> 
> When user enables profiling feature, we need to insert extra instructions to
> record and store the timestamps.
> By now, the function pass will just insert the requred instructions at the head
> of first 20 blocks. Later, we will support to insert timestamps at any point in
> the code.
> 
> Signed-off-by: Junyan He <junyan.he at linux.intel.com>
> Signed-off-by: Bai Yannan <yannan.bai at intel.com>
> ---
>  backend/src/CMakeLists.txt          |    1 +
>  backend/src/llvm/llvm_profiling.cpp |  210
> +++++++++++++++++++++++++++++++++++
>  2 files changed, 211 insertions(+)
>  create mode 100644 backend/src/llvm/llvm_profiling.cpp
> 
> diff --git a/backend/src/CMakeLists.txt b/backend/src/CMakeLists.txt index
> daab320..e56df5e 100644
> --- a/backend/src/CMakeLists.txt
> +++ b/backend/src/CMakeLists.txt
> @@ -87,6 +87,7 @@ set (GBE_SRC
>      llvm/llvm_intrinsic_lowering.cpp
>      llvm/llvm_barrier_nodup.cpp
>      llvm/llvm_printf_parser.cpp
> +    llvm/llvm_profiling.cpp
>      llvm/ExpandConstantExpr.cpp
>      llvm/ExpandUtils.cpp
>      llvm/PromoteIntegers.cpp
> diff --git a/backend/src/llvm/llvm_profiling.cpp
> b/backend/src/llvm/llvm_profiling.cpp
> new file mode 100644
> index 0000000..c52e241
> --- /dev/null
> +++ b/backend/src/llvm/llvm_profiling.cpp
> @@ -0,0 +1,210 @@
> +/*
> + * 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/>.
> + *
> + */
> +
> +/**
> + * \file llvm_profiling.cpp
> + * This file will insert some instructions for each profiling point.
> + *
> + */
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +
> +#include "llvm/Config/llvm-config.h"
> +#if LLVM_VERSION_MINOR <= 2
> +#include "llvm/Function.h"
> +#include "llvm/InstrTypes.h"
> +#include "llvm/Instructions.h"
> +#include "llvm/IntrinsicInst.h"
> +#include "llvm/Module.h"
> +#else
> +#include "llvm/IR/Function.h"
> +#include "llvm/IR/InstrTypes.h"
> +#include "llvm/IR/Instructions.h"
> +#include "llvm/IR/IntrinsicInst.h"
> +#include "llvm/IR/Module.h"
> +#endif  /* LLVM_VERSION_MINOR <= 2 */
> +#include "llvm/Pass.h"
> +#if LLVM_VERSION_MINOR <= 1
> +#include "llvm/Support/IRBuilder.h"
> +#elif LLVM_VERSION_MINOR == 2
> +#include "llvm/IRBuilder.h"
> +#else
> +#include "llvm/IR/IRBuilder.h"
> +#endif /* LLVM_VERSION_MINOR <= 1 */
> +
> +#if LLVM_VERSION_MINOR >= 5
> +#include "llvm/IR/CallSite.h"
> +#include "llvm/IR/CFG.h"
> +#else
> +#include "llvm/Support/CallSite.h"
> +#include "llvm/Support/CFG.h"
> +#endif
> +
> +#include "llvm/Support/raw_ostream.h"
> +#include "llvm/IR/Attributes.h"
> +
> +#include "llvm/llvm_gen_backend.hpp"
> +#include "sys/map.hpp"
> +
> +#include <iostream>
> +#include <vector>
> +
> +
> +using namespace llvm;
> +using std::vector;
> +
> +
> +namespace gbe
> +{
> +  using namespace ir;
> +
> +  class ProfilingInserter : public FunctionPass  {
> +  public:
> +    static char ID;
> +    Module* module;
> +    IRBuilder<>* builder;
> +    Type* intTy;
> +    Type *ptrTy;
> +    int profilingType;
> +
> +    ProfilingInserter(int profiling) : FunctionPass(ID), profilingType(profiling)
> +    {
> +      module = NULL;
> +      builder = NULL;
> +      intTy = NULL;
> +      ptrTy = NULL;
> +    }
> +
> +    ~ProfilingInserter(void)
> +    {
> +    }
> +
> +    virtual const char *getPassName() const
> +    {
> +      return "Timestamp Parser";
> +    }
> +
> +    virtual bool runOnFunction(llvm::Function &F);  };
> +
> +  bool ProfilingInserter::runOnFunction(llvm::Function &F)  {
> +    bool changed = false;
> +    int pointNum = 0;
> +
> +    switch (F.getCallingConv()) {
> +#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR <= 2
> +      case CallingConv::PTX_Device:
> +        return false;
> +      case CallingConv::PTX_Kernel:
> +#else
> +      case CallingConv::C:
> +      case CallingConv::Fast:
> +      case CallingConv::SPIR_KERNEL:
> +#endif
> +        break;
> +      default:
> +        GBE_ASSERTM(false, "Unsupported calling convention");
> +    }
> +
> +    // As we inline all function calls, so skip non-kernel functions
> +    bool bKernel = isKernelFunction(F);
> +    if (!bKernel) return changed;
> +
> +    module = F.getParent();
> +    intTy = IntegerType::get(module->getContext(), 32);
> +    ptrTy = Type::getInt32PtrTy(module->getContext(), 1);
> +    builder = new IRBuilder<>(module->getContext());
> +
> +    /* alloc a new buffer ptr to collect the timestamps. */
> +    builder->SetInsertPoint(F.begin()->begin());
> +    llvm::Constant *profilingBuf = module-
> >getGlobalVariable("__gen_ocl_profiling_buf");
> +    if (!profilingBuf) {
> +      profilingBuf = new GlobalVariable(*module, intTy, false,
> +          GlobalVariable::ExternalLinkage, nullptr,
> StringRef("__gen_ocl_profiling_buf"),
> +          nullptr, GlobalVariable::NotThreadLocal, 1);
> +    }
> +
> +    changed = true;
> +
> +    for (llvm::Function::iterator B = F.begin(), BE = F.end(); B != BE; B++) {
> +      /* Skip the empty blocks. */
> +      if (B->empty())
> +        continue;
> +
> +      BasicBlock::iterator instI = B->begin();
> +      for ( ; instI != B->end(); instI++) {
> +        if (dyn_cast<llvm::PHINode>(instI))
> +          continue;
> +        if (dyn_cast<llvm::ReturnInst>(instI)) {
> +          instI++;
> +          GBE_ASSERT(instI == B->end());
> +          break;
> +        }
> +        if (dyn_cast<llvm::BranchInst>(instI)) {
> +          instI++;
> +          GBE_ASSERT(instI == B->end());
> +          break;
> +        }
> +        break;
> +      }
> +
> +      if (instI == B->end())
> +        continue;
> +
> +      if (pointNum >= 20) // To many timestamp.
> +        continue;
> +
> +      // Insert the first one at beginning of not PHI.
> +      builder->SetInsertPoint(instI);
> +      /* Add the timestamp store function call. */
> +      // __gen_ocl_store_timestamp(int nth, int type);
> +      builder->CreateCall2(cast<llvm::Function>(module-
> >getOrInsertFunction(
> +              "__gen_ocl_calc_timestamp", Type::getVoidTy(module-
> >getContext()),
> +              IntegerType::getInt32Ty(module->getContext()),
> +              IntegerType::getInt32Ty(module->getContext()),
> +              NULL)),
> +          /* the args */ ConstantInt::get(intTy, pointNum++),
> ConstantInt::get(intTy, profilingType));
> +    }
> +    /* At the end and before return, we want to store the profiling info. */
> +    llvm::Function::iterator BE = F.end();
> +    BE--;
> +    BasicBlock::iterator retInst = BE->end();
> +    retInst--;
> +    GBE_ASSERT(dyn_cast<llvm::ReturnInst>(retInst));
It is not correct assume the last instruction of last BB is ReturnInst, because beignet support goto. Can't assert here.


> +    builder->SetInsertPoint(retInst);
> +    builder->CreateCall2(cast<llvm::Function>(module->getOrInsertFunction(
> +            "__gen_ocl_store_profiling", Type::getVoidTy(module-
> >getContext()),
> +            ptrTy,
> +            IntegerType::getInt32Ty(module->getContext()),
> +            NULL)),
> +        /* the args */profilingBuf, ConstantInt::get(intTy,
> + profilingType));
> +
> +    delete builder;
> +    return changed;
> +  }
> +
> +  FunctionPass* createProfilingInserterPass(int profilingType)  {
> +    return new ProfilingInserter(profilingType);  }  char
> + ProfilingInserter::ID = 0;
> +
> +} // end namespace
> --
> 1.7.9.5
> 
> 
> 
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list