Ignore:
Timestamp:
Apr 17, 2018, 6:33:56 PM (18 months ago)
Author:
cameron
Message:

New generic bitblock_mask_from, bitblock_set_bit small field simd_popcount

Location:
icGREP/icgrep-devel/icgrep
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_builder.cpp

    r5956 r5972  
    286286    }
    287287    return w;
     288}
     289
     290Value * IDISA_Builder::simd_popcount(unsigned fw, Value * a) {
     291    if (fw == 1) {
     292        return a;
     293    } else if (fw == 2) {
     294        // For each 2-bit field ab we can use the subtraction ab - 0a to generate
     295        // the popcount without carry/borrow from the neighbouring 2-bit field.
     296        // case 00:  ab - 0a = 00 - 00 = 00
     297        // case 01:  ab - 0a = 01 - 00 = 01
     298        // case 10:  ab - 0a = 10 - 01 = 01 (no borrow)
     299        // case 11:  ab - 0a = 11 - 01 = 10
     300        return simd_sub(64, a, simd_srli(64, simd_and(simd_himask(2), a), 1));
     301    } else if (fw == 4) {
     302        Value * c = simd_popcount(fw/2, a);
     303        c = simd_add(64, simd_and(c, simd_lomask(fw)), simd_srli(fw, c, fw/2));
     304        return c;
     305    } else {
     306        return CreatePopcount(fwCast(fw, a));
     307    }
    288308}
    289309
     
    567587
    568588Value * IDISA_Builder::bitblock_mask_from(Value * pos) {
    569     Type * const ty = getIntNTy(getBitBlockWidth());
    570     Constant * const ONES = ConstantInt::getAllOnesValue(ty);
    571     Constant * const ZEROES = ConstantInt::getNullValue(ty);
    572     Constant * const BIT_BLOCK_WIDTH = ConstantInt::get(pos->getType(), getBitBlockWidth());
    573     Value * const mask = CreateSelect(CreateICmpULT(pos, BIT_BLOCK_WIDTH), CreateShl(ONES, CreateZExt(pos, ty)), ZEROES);
    574     return bitCast(mask);
     589    Value * p = CreateZExtOrTrunc(pos, getSizeTy());
     590    const unsigned fw = getSizeTy()->getBitWidth();
     591    const auto field_count = mBitBlockWidth / fw;
     592    Constant * fwVal = ConstantInt::get(getSizeTy(), fw);
     593    Constant * poaBase[field_count];
     594    for (unsigned i = 0; i < field_count; i++) {
     595        poaBase[i] = ConstantInt::get(getSizeTy(), fw * i);
     596    }
     597    Value * posBaseVec = ConstantVector::get({poaBase, field_count});
     598    Value * mask1 = CreateSExt(CreateICmpUGT(posBaseVec, simd_fill(fw, pos)), fwVectorType(fw));
     599    Value * bitField = CreateShl(ConstantInt::getAllOnesValue(getSizeTy()), CreateURem(p, fwVal));
     600    Value * inBitBlock = CreateICmpULT(p, getSize(mBitBlockWidth));
     601    Value * fieldNo = CreateUDiv(p, fwVal);
     602    Value * const final_mask = CreateSelect(inBitBlock, CreateInsertElement(mask1, bitField, fieldNo), mask1);
     603    return bitCast(final_mask);
    575604}
    576605
    577606Value * IDISA_Builder::bitblock_set_bit(Value * pos) {
    578     Type * const ty = getIntNTy(getBitBlockWidth());
    579     return bitCast(CreateShl(ConstantInt::get(ty, 1), CreateZExt(pos, ty)));
     607    Value * p = CreateZExtOrTrunc(pos, getSizeTy());
     608    const unsigned fw = getSizeTy()->getBitWidth();
     609    Constant * fwVal = ConstantInt::get(getSizeTy(), fw);
     610    Value * bitField = CreateShl(ConstantInt::get(getSizeTy(), 1), CreateURem(p, fwVal));
     611    Value * fieldNo = CreateUDiv(p, fwVal);
     612    return bitCast(CreateInsertElement(Constant::getNullValue(fwVectorType(fw)), bitField, fieldNo));
    580613}
    581614
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_builder.h

    r5865 r5972  
    126126    virtual llvm::Value * simd_pdep(unsigned fw, llvm::Value * v, llvm::Value * deposit_mask);
    127127   
    128     llvm::Value * simd_popcount(unsigned fw, llvm::Value * a) {
    129         if (LLVM_UNLIKELY(fw < 8)) {
    130             assert ("field width is less than 8" && false);
    131             llvm::report_fatal_error("Unsupported field width: popcount " + std::to_string(fw));
    132         }
    133         return CreatePopcount(fwCast(fw, a));
    134     }
     128    virtual llvm::Value * simd_popcount(unsigned fw, llvm::Value * a);
    135129
    136130    virtual llvm::Value * simd_bitreverse(unsigned fw, llvm::Value * a);
  • icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.cpp

    r5855 r5972  
    752752                            case TypeId::GreaterThanEquals:
    753753                            case TypeId::LessThan:
    754                                 comp = b->simd_ult(n, lhv, rhv);
     754                                //comp = b->simd_ult(n, lhv, rhv);
     755                                comp = b->CreateICmpULT(b->fwCast(n, lhv), b->fwCast(n, rhv));
    755756                                break;
    756757                            case TypeId::Equals:
    757758                            case TypeId::NotEquals:
    758                                 comp = b->simd_eq(n, lhv, rhv);
     759                                comp = b->CreateICmpEQ(b->fwCast(n, lhv), b->fwCast(n, rhv));
    759760                                break;
    760761                            case TypeId::LessThanEquals:
    761762                            case TypeId::GreaterThan:
    762                                 comp = b->simd_ugt(n, lhv, rhv);
     763                                comp = b->CreateICmpUGT(b->fwCast(n, lhv), b->fwCast(n, rhv));
    763764                                break;
    764765                            default: llvm_unreachable("invalid vector operator id");
    765766                        }
    766                         Value * const mask = b->CreateZExtOrTrunc(b->hsimd_signmask(n, comp), fw);
     767                        Value * const mask = b->CreateBitCast(comp, b->getIntNTy(m));
    767768                        value = b->mvmd_insert(m, value, mask, i);
    768769                    }
Note: See TracChangeset for help on using the changeset viewer.