Changeset 4301


Ignore:
Timestamp:
Nov 11, 2014, 11:32:55 PM (4 years ago)
Author:
linmengl
Message:

check-in the code with USE_TWO_UADD_OVERFLOW flag. The corectness check passed.

Location:
icGREP/icgrep-devel/icgrep/pablo
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.cpp

    r4297 r4301  
    331331
    332332#ifdef USE_UADD_OVERFLOW
     333#ifdef USE_TWO_UADD_OVERFLOW
     334    // Type Definitions for llvm.uadd.with.overflow.carryin.i128 or .i256
     335    std::vector<Type*>StructTy_0_fields;
     336    StructTy_0_fields.push_back(IntegerType::get(mMod->getContext(), BLOCK_SIZE));
     337    StructTy_0_fields.push_back(IntegerType::get(mMod->getContext(), 1));
     338    StructType *StructTy_0 = StructType::get(mMod->getContext(), StructTy_0_fields, /*isPacked=*/false);
     339
     340    std::vector<Type*>FuncTy_1_args;
     341    FuncTy_1_args.push_back(IntegerType::get(mMod->getContext(), BLOCK_SIZE));
     342    FuncTy_1_args.push_back(IntegerType::get(mMod->getContext(), BLOCK_SIZE));
     343    FunctionType* FuncTy_1 = FunctionType::get(
     344                                              /*Result=*/StructTy_0,
     345                                              /*Params=*/FuncTy_1_args,
     346                                              /*isVarArg=*/false);
     347
     348    mFunctionUaddOverflow = mMod->getFunction("llvm.uadd.with.overflow.i" +
     349                                              std::to_string(BLOCK_SIZE));
     350    if (!mFunctionUaddOverflow) {
     351        mFunctionUaddOverflow= Function::Create(
     352          /*Type=*/ FuncTy_1,
     353          /*Linkage=*/ GlobalValue::ExternalLinkage,
     354          /*Name=*/ "llvm.uadd.with.overflow.i" + std::to_string(BLOCK_SIZE), mMod); // (external, no body)
     355        mFunctionUaddOverflow->setCallingConv(CallingConv::C);
     356    }
     357    AttributeSet mFunctionUaddOverflowPAL;
     358    {
     359        SmallVector<AttributeSet, 4> Attrs;
     360        AttributeSet PAS;
     361        {
     362          AttrBuilder B;
     363          B.addAttribute(Attribute::NoUnwind);
     364          B.addAttribute(Attribute::ReadNone);
     365          PAS = AttributeSet::get(mMod->getContext(), ~0U, B);
     366        }
     367
     368        Attrs.push_back(PAS);
     369        mFunctionUaddOverflowPAL = AttributeSet::get(mMod->getContext(), Attrs);
     370    }
     371    mFunctionUaddOverflow->setAttributes(mFunctionUaddOverflowPAL);
     372#else
    333373    // Type Definitions for llvm.uadd.with.overflow.carryin.i128 or .i256
    334374    std::vector<Type*>StructTy_0_fields;
     
    346386                                              /*isVarArg=*/false);
    347387
    348     mFunctionUaddOverflow = mMod->getFunction("llvm.uadd.with.overflow.carryin.i" +
     388    mFunctionUaddOverflowCarryin = mMod->getFunction("llvm.uadd.with.overflow.carryin.i" +
    349389                                              std::to_string(BLOCK_SIZE));
    350     if (!mFunctionUaddOverflow) {
    351         mFunctionUaddOverflow = Function::Create(
     390    if (!mFunctionUaddOverflowCarryin) {
     391        mFunctionUaddOverflowCarryin = Function::Create(
    352392          /*Type=*/ FuncTy_1,
    353393          /*Linkage=*/ GlobalValue::ExternalLinkage,
    354394          /*Name=*/ "llvm.uadd.with.overflow.carryin.i" + std::to_string(BLOCK_SIZE), mMod); // (external, no body)
    355         mFunctionUaddOverflow->setCallingConv(CallingConv::C);
    356     }
    357     AttributeSet mFunctionUaddOverflowPAL;
     395        mFunctionUaddOverflowCarryin->setCallingConv(CallingConv::C);
     396    }
     397    AttributeSet mFunctionUaddOverflowCarryinPAL;
    358398    {
    359399        SmallVector<AttributeSet, 4> Attrs;
     
    367407
    368408        Attrs.push_back(PAS);
    369         mFunctionUaddOverflowPAL = AttributeSet::get(mMod->getContext(), Attrs);
    370     }
    371     mFunctionUaddOverflow->setAttributes(mFunctionUaddOverflowPAL);
     409        mFunctionUaddOverflowCarryinPAL = AttributeSet::get(mMod->getContext(), Attrs);
     410    }
     411    mFunctionUaddOverflowCarryin->setAttributes(mFunctionUaddOverflowCarryinPAL);
     412#endif
    372413#endif
    373414
     
    828869
    829870#ifdef USE_UADD_OVERFLOW
     871#ifdef USE_TWO_UADD_OVERFLOW
     872PabloCompiler::SumWithOverflowPack PabloCompiler::callUaddOverflow(Value* int128_e1, Value* int128_e2) {
     873    std::vector<Value*> struct_res_params;
     874    struct_res_params.push_back(int128_e1);
     875    struct_res_params.push_back(int128_e2);
     876    CallInst* struct_res = CallInst::Create(mFunctionUaddOverflow, struct_res_params, "uadd_overflow_res", mBasicBlock);
     877    struct_res->setCallingConv(CallingConv::C);
     878    struct_res->setTailCall(false);
     879    AttributeSet struct_res_PAL;
     880    struct_res->setAttributes(struct_res_PAL);
     881
     882    SumWithOverflowPack ret;
     883
     884    std::vector<unsigned> int128_sum_indices;
     885    int128_sum_indices.push_back(0);
     886    ret.sum = ExtractValueInst::Create(struct_res, int128_sum_indices, "sum", mBasicBlock);
     887
     888    std::vector<unsigned> int1_obit_indices;
     889    int1_obit_indices.push_back(1);
     890    ret.obit = ExtractValueInst::Create(struct_res, int1_obit_indices, "obit", mBasicBlock);
     891
     892    return ret;
     893}
     894#else
    830895PabloCompiler::SumWithOverflowPack PabloCompiler::callUaddOverflow(Value* int128_e1, Value* int128_e2, Value* int1_cin) {
    831896    std::vector<Value*> struct_res_params;
     
    833898    struct_res_params.push_back(int128_e2);
    834899    struct_res_params.push_back(int1_cin);
    835     CallInst* struct_res = CallInst::Create(mFunctionUaddOverflow, struct_res_params, "uadd_overflow_res", mBasicBlock);
     900    CallInst* struct_res = CallInst::Create(mFunctionUaddOverflowCarryin, struct_res_params, "uadd_overflow_res", mBasicBlock);
    836901    struct_res->setCallingConv(CallingConv::C);
    837902    struct_res->setTailCall(false);
     
    852917}
    853918#endif
     919#endif
    854920
    855921Value* PabloCompiler::genAddWithCarry(Value* e1, Value* e2) {
     
    859925    const int carryIdx = mCarryQueueIdx++;
    860926    Value* carryq_value = genCarryInLoad(carryIdx);
    861 
    862 #ifdef USE_UADD_OVERFLOW
    863     //use llvm.uadd.with.overflow.i128 or i256
    864     ConstantInt* const_int32_6 = ConstantInt::get(mMod->getContext(), APInt(32, StringRef("0"), 10));
     927#ifdef USE_TWO_UADD_OVERFLOW
     928    //This is the ideal implementation, which uses two uadd.with.overflow
     929    //The back end should be able to recognize this pattern and combine it into uadd.with.overflow.carryin
    865930    CastInst* int128_e1 = new BitCastInst(e1, IntegerType::get(mMod->getContext(), BLOCK_SIZE), "e1_128", mBasicBlock);
    866931    CastInst* int128_e2 = new BitCastInst(e2, IntegerType::get(mMod->getContext(), BLOCK_SIZE), "e2_128", mBasicBlock);
     932    CastInst* int128_carryq_value = new BitCastInst(carryq_value, IntegerType::get(mMod->getContext(), BLOCK_SIZE), "carryq_128", mBasicBlock);
     933
     934    SumWithOverflowPack sumpack0, sumpack1;
     935
     936    sumpack0 = callUaddOverflow(int128_e1, int128_e2);
     937    sumpack1 = callUaddOverflow(sumpack0.sum, int128_carryq_value);
     938
     939    Value* obit = b.CreateOr(sumpack0.obit, sumpack1.obit, "carry_bit");
     940    Value* sum = b.CreateBitCast(sumpack1.sum, mBitBlockType, "ret_sum");
     941
     942    /*obit is the i1 carryout, zero extend and insert it into a v2i64 or v4i64 vector.*/
     943    ConstantAggregateZero* const_packed_5 = ConstantAggregateZero::get(mBitBlockType);
     944    ConstantInt* const_int32_6 = ConstantInt::get(mMod->getContext(), APInt(32, StringRef("0"), 10));
     945    CastInst* int64_o0 = new ZExtInst(obit, IntegerType::get(mMod->getContext(), 64), "o0", mBasicBlock);
     946    InsertElementInst* carry_out = InsertElementInst::Create(const_packed_5, int64_o0, const_int32_6, "carry_out", mBasicBlock);
     947
     948#elif defined USE_UADD_OVERFLOW
     949    //use llvm.uadd.with.overflow.i128 or i256
     950    CastInst* int128_e1 = new BitCastInst(e1, IntegerType::get(mMod->getContext(), BLOCK_SIZE), "e1_128", mBasicBlock);
     951    CastInst* int128_e2 = new BitCastInst(e2, IntegerType::get(mMod->getContext(), BLOCK_SIZE), "e2_128", mBasicBlock);
     952
     953    //get i1 carryin from iBLOCK_SIZE
     954    ConstantInt* const_int32_6 = ConstantInt::get(mMod->getContext(), APInt(32, StringRef("0"), 10));
    867955    ExtractElementInst * int64_carryq_value = ExtractElementInst::Create(carryq_value, const_int32_6, "carryq_64", mBasicBlock);
    868956    CastInst* int1_carryq_value = new TruncInst(int64_carryq_value, IntegerType::get(mMod->getContext(), 1), "carryq_1", mBasicBlock);
     957
    869958    SumWithOverflowPack sumpack0;
    870959    sumpack0 = callUaddOverflow(int128_e1, int128_e2, int1_carryq_value);
    871960    Value* obit = sumpack0.obit;
    872961    Value* sum = b.CreateBitCast(sumpack0.sum, mBitBlockType, "sum");
     962
    873963    /*obit is the i1 carryout, zero extend and insert it into a v2i64 or v4i64 vector.*/
    874964    ConstantAggregateZero* const_packed_5 = ConstantAggregateZero::get(mBitBlockType);
    875965    CastInst* int64_o0 = new ZExtInst(obit, IntegerType::get(mMod->getContext(), 64), "o0", mBasicBlock);
    876966    InsertElementInst* carry_out = InsertElementInst::Create(const_packed_5, int64_o0, const_int32_6, "carry_out", mBasicBlock);
    877 #else
    878 
    879 #if (BLOCK_SIZE == 128)
     967#elif (BLOCK_SIZE == 128)
    880968    //calculate carry through logical ops
    881969    Value* carrygen = b.CreateAnd(e1, e2, "carrygen");
     
    891979    //BLOCK_SIZE == 256, there is no other implementation
    892980    static_assert(false, "Add with carry for 256-bit bitblock requires USE_UADD_OVERFLOW");
    893 #endif
    894 
    895 #endif
     981#endif //USE_TWO_UADD_OVERFLOW
     982
    896983    genCarryOutStore(carry_out, carryIdx);
    897984    return sum;
  • icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.h

    r4289 r4301  
    1111//#define USE_UADD_OVERFLOW
    1212//#define USE_LONG_INTEGER_SHIFT
     13//#define USE_TWO_UADD_OVERFLOW
     14
     15#if defined(USE_TWO_UADD_OVERFLOW) && !defined(USE_UADD_OVERFLOW)
     16static_assert(false, "Need to turn on them together.");
     17#endif
    1318
    1419//Pablo Expressions
     
    8388
    8489    #ifdef USE_UADD_OVERFLOW
     90    #ifdef USE_TWO_UADD_OVERFLOW
     91    Function* mFunctionUaddOverflow;
     92    SumWithOverflowPack callUaddOverflow(Value *e1, Value *e2);
     93    #else
     94    Function* mFunctionUaddOverflowCarryin;
    8595    SumWithOverflowPack callUaddOverflow(Value *e1, Value *e2, Value *cin);
    86     Function* mFunctionUaddOverflow;
    8796    #endif
     97    #endif
     98
    8899
    89100    StringToValueMap                    mMarkerMap;
Note: See TracChangeset for help on using the changeset viewer.