[Beignet] [Printf][PATCH 06/11] Implement emision of printf instruction.

He Junyan junyan.he at inbox.com
Wed Jan 27 20:33:05 PST 2016


On Thu, Jan 21, 2016 at 11:30:21AM +0800, Yan Wang wrote:
> Date: Thu, 21 Jan 2016 11:30:21 +0800
> From: Yan Wang <yan.wang at linux.intel.com>
> To: beignet at lists.freedesktop.org
> Cc: Yan Wang <yan.wang at linux.intel.com>
> Subject: [Beignet] [Printf][PATCH 06/11] Implement emision of printf
>  instruction.
> X-Mailer: git-send-email 2.5.0
> 
> Contributor: Junyan He <junyan.he at linux.intel.com>
> Signed-off-by: Yan Wang <yan.wang at linux.intel.com>
> ---
>  backend/src/ir/context.hpp            |  5 ++
>  backend/src/llvm/llvm_gen_backend.cpp | 89 ++++++++++++++++++++++++++++-------
>  2 files changed, 78 insertions(+), 16 deletions(-)
> 
I think it is better to write another patch to type TUPLE logic
> diff --git a/backend/src/ir/context.hpp b/backend/src/ir/context.hpp
> index b95741f..877d639 100644
> --- a/backend/src/ir/context.hpp
> +++ b/backend/src/ir/context.hpp
> @@ -149,6 +149,11 @@ namespace ir {
>        GBE_ASSERTM(fn != NULL, "No function currently defined");
>        return fn->file.appendArrayTuple(reg, regNum);
>      }
> +    /*! Make a tuple from an array of types */
> +    INLINE Tuple arrayTypeTuple(const ir::Type *type, uint32_t num) {
> +      GBE_ASSERTM(fn != NULL, "No function currently defined");
> +      return fn->file.appendArrayTypeTuple((uint8_t*)type, num);
> +    }
>      /*! We just use variadic templates to forward instruction functions */
>  #define DECL_INSN(NAME, FAMILY) \
>      template <typename... Args> INLINE void NAME(Args...args);
> diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
> index dba9dba..cc736d7 100644
> --- a/backend/src/llvm/llvm_gen_backend.cpp
> +++ b/backend/src/llvm/llvm_gen_backend.cpp
> @@ -486,6 +486,9 @@ namespace gbe
>      typedef map<Value *, SmallVector<Value *, 4>>::iterator PtrOrigMapIter;
>      // map pointer source to bti
>      map<Value *, unsigned> BtiMap;
> +    // map printf pointer source to bti
> +    int printfBti;
> +    uint32_t printfNum;
>      // map ptr to its bti register
>      map<Value *, Value *> BtiValueMap;
>      // map ptr to it's base
> @@ -520,6 +523,8 @@ namespace gbe
>          unit(unit),
>          ctx(unit),
>          regTranslator(ctx),
> +        printfBti(-1),
Also need to reset printfBti for each runOnFunction.

> +        printfNum(0),
>          LI(0),
>          TheModule(0),
>          btiBase(BTI_RESERVED_NUM),
> @@ -594,7 +599,7 @@ namespace gbe
>      /*! For all possible pointers, GlobalVariable, function pointer argument,
>          alloca instruction, find their pointer escape points */
>      void analyzePointerOrigin(Function &F);
> -    unsigned getNewBti(Value *origin, bool isImage);
> +    unsigned getNewBti(Value *origin, bool force);
>      void assignBti(Function &F);
>      bool isSingleBti(Value *Val);
>      Value *getBtiRegister(Value *v);
> @@ -717,12 +722,7 @@ namespace gbe
>      // handle load of dword/qword with unaligned address
>      void emitUnalignedDQLoadStore(ir::Register ptr, Value *llvmValues, ir::AddressSpace addrSpace, ir::Register bti, bool isLoad, bool dwAligned, bool fixedBTI);
>      void visitInstruction(Instruction &I) {NOT_SUPPORTED;}
> -    void* getPrintfInfo(CallInst* inst)
> -    {
> -      if (&unit.printfs[inst])
> -        return (void*)&unit.printfs[inst];
> -      return NULL;
> -    }
> +    ir::PrintfSet::PrintfFmt* getPrintfInfo(CallInst* inst) { return &unit.printfs[inst]; }

I think
    ir::PrintfSet::PrintfFmt* getPrintfInfo(CallInst* inst) {
	      if (unit.printfs.find(inst) == unit.printfs.end())
	        return NULL;
	
	     return &unit.printfs[inst];
	 }

would be better

>      private:
>        void setDebugInfo_CTX(llvm::Instruction * insn); // store the debug infomation in context for subsequently passing to Gen insn
>        ir::ImmediateIndex processConstantImmIndexImpl(Constant *CPV, int32_t index = 0u);
> @@ -1127,21 +1127,15 @@ namespace gbe
>      }
>    }
>  
> -  unsigned GenWriter::getNewBti(Value *origin, bool isImage) {
> +  unsigned GenWriter::getNewBti(Value *origin, bool force) {
>      unsigned new_bti = 0;
> -    if (isImage) {
> +    if (force) {
>        new_bti = btiBase;
>        incBtiBase();
>        return new_bti;
>      }
>  
> -    if(origin->getName().equals(StringRef("__gen_ocl_printf_buf"))) {
> -      new_bti = btiBase;
> -      incBtiBase();
> -    } else if (origin->getName().equals(StringRef("__gen_ocl_printf_index_buf"))) {
> -      new_bti = btiBase;
> -      incBtiBase();
> -    } else if (origin->getName().equals(StringRef("__gen_ocl_profiling_buf"))) {
> +    if (origin->getName().equals(StringRef("__gen_ocl_profiling_buf"))) {
>        new_bti = btiBase;
>        incBtiBase();
>      }
> @@ -3716,6 +3710,16 @@ namespace gbe
>          this->newRegister(&I);
>          break;
>        case GEN_OCL_PRINTF:
> +        this->newRegister(&I);  // fall through
> +      case GEN_OCL_PUTS:
> +      {
> +         // We need a new BTI as printf output.
> +         if (printfBti < 0) {
> +           printfBti = this->getNewBti(&I, true);
> +           ctx.getFunction().getPrintfSet()->setBufBTI(printfBti);
> +         }
> +         break;
> +      }
>        case GEN_OCL_CALC_TIMESTAMP:
>        case GEN_OCL_STORE_PROFILING:
>        case GEN_OCL_DEBUGWAIT:
> @@ -4527,6 +4531,59 @@ namespace gbe
>  
>            case GEN_OCL_PRINTF:
>            {
> +            ir::PrintfSet::PrintfFmt* fmt = getPrintfInfo(&I);
I think add a check here.

            if (fmt == NULL) {
	             break; //Maybe printf(""), NULL string, just ignore.
	          }

> +            ctx.getFunction().getPrintfSet()->append(printfNum, fmt);
> +
> +            vector<ir::Register> tupleData;
> +            vector<ir::Type> tupleTypeData;
> +            int argNum = static_cast<int>(I.getNumOperands());
> +            argNum -= 2; // no fmt and last NULL.
> +            int realArgNum = argNum;
> +
> +            for (int n = 0; n < argNum; n++) {
> +              /* First, ignore %s, the strings are recorded and not passed to GPU. */
> +              llvm::Constant* args = dyn_cast<llvm::ConstantExpr>(I.getOperand(n + 1));
> +              llvm::Constant* args_ptr = NULL;
> +              if (args)
> +                args_ptr = dyn_cast<llvm::Constant>(args->getOperand(0));
> +
> +              if (args_ptr) {
> +                ConstantDataSequential* fmt_arg = dyn_cast<ConstantDataSequential>(args_ptr->getOperand(0));
> +                if (fmt_arg && fmt_arg->isCString()) {
> +                  realArgNum--;
> +                  continue;
> +                }
> +              }
> +
> +              Type * type = I.getOperand(n + 1)->getType();
> +              if (type->isVectorTy()) {
> +                uint32_t srcElemNum = 0;
> +                Value *srcValue = I.getOperand(n + 1);
> +                ir::Type srcType = getVectorInfo(ctx, srcValue, srcElemNum);
> +                GBE_ASSERT(!(srcType == ir::TYPE_S64 || srcType == ir::TYPE_DOUBLE));
> +
> +                uint32_t elemID = 0;
> +                for (elemID = 0; elemID < srcElemNum; ++elemID) {
> +                  ir::Register reg = getRegister(srcValue, elemID);
> +                  tupleData.push_back(reg);
> +                  tupleTypeData.push_back(srcType);
> +                }
> +                realArgNum += srcElemNum - 1;
> +              } else {
> +                ir::Register reg = getRegister(I.getOperand(n + 1));
> +                tupleData.push_back(reg);
> +                tupleTypeData.push_back(getType(ctx, I.getOperand(n + 1)->getType()));
> +              }
> +            }
> +
> +            ir::Tuple tuple;
> +            ir::Tuple typeTuple;
> +            if (realArgNum > 0) {
> +              tuple = ctx.arrayTuple(&tupleData[0], realArgNum);
> +              typeTuple = ctx.arrayTypeTuple(&tupleTypeData[0], realArgNum);
> +            }
> +            ctx.PRINTF(getRegister(&I), tuple, typeTuple, realArgNum, printfBti, printfNum);
> +            printfNum++;
>              break;
>            }
>            case GEN_OCL_CALC_TIMESTAMP:
> -- 
> 2.4.3
> 
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet




More information about the Beignet mailing list