unsigned int test_lzcnt_u32(unsigned int __X) { // CHECK: @llvm.ctlz.i32 return _lzcnt_u32(__X); }
void APLWAHSet::fromVector(const vector<int>& v){ length = v.size(); chunkMax = (v.back()/31) + 1; bitmap.clear(); bitmap.reserve(chunkMax/4); int CCount = 0; vector<int>::const_iterator ICount = v.begin(); vector<int>::const_iterator lastLitStart = v.begin(); vector<int>::const_iterator lastLitEnd = v.begin(); Word lastLit = 0; while(ICount != v.end()){ int litStart = *ICount; //本Literal的第一个数字 int litCCount = litStart/31; int FillCount = litCCount - CCount; vector<int>::const_iterator IEnd = ICount; //ICount当前data的指针,IEnd本Literal的最后一个数字在data中的index int litEnd = litCCount*31 + 31; //本Literal的边界末尾 Word lit = 0x80000000; while(IEnd != v.end() && *IEnd < litEnd){ lit |= 1<<(*IEnd%31); IEnd ++; } if(lastLitStart == lastLitEnd){ // 没有预备L if(FillCount == 0){ // 得到L if(IEnd - ICount < 4){ //之后可能被压缩,作为后备L lastLitStart = ICount; lastLitEnd = IEnd; lastLit = lit; } else{ //不可能被压缩,直接输出 bitmap.push_back(lit); } } else{ // 得到 F与L if(IEnd - ICount < 4){ //可能生成FL int n = (_lzcnt_u32(FillCount) - 5)/5; if(IEnd - ICount > n){ //Fill太大,不能生成FL,L留作预备 bitmap.push_back(FillCount); lastLitStart = ICount; lastLitEnd = IEnd; lastLit = lit; } else{ //可以生成FL FillCount |= (IEnd - ICount) << 27; for(vector<int>::const_iterator itr = ICount;itr < IEnd;itr++){ FillCount |= (*itr%31) << (22 - 5*(itr - ICount)) ; } bitmap.push_back(FillCount); } } else{ //L太脏,不能生成FL bitmap.push_back(FillCount); bitmap.push_back(lit); } } } else{ //有预备L if(FillCount==0){ // L+L if(IEnd - ICount < 4){ //后一个可能可能被压缩 if(IEnd - ICount + lastLitEnd - lastLitStart < 6){ //LL 可以生成 lit = 0; lit |= (lastLitEnd - lastLitStart) << 29; lit |= (IEnd - ICount) << 27; for(vector<int>::const_iterator itr = lastLitStart;itr < lastLitEnd;itr++){ lit |= (*itr%31) << (22 - 5*(itr - lastLitStart)) ; } int countStart = (ICount - lastLitEnd) + (lastLitStart - v.begin()); for(vector<int>::const_iterator itr = ICount;itr < IEnd;itr++){ lit |= (*itr%31) << (22 - 5*(itr - v.begin() - countStart)) ; } bitmap.push_back(lit); lastLitStart = lastLitEnd; } else{ // LL不能生成,输出预备L,现有L留作预备 bitmap.push_back(lastLit); lastLit = lit; lastLitStart = ICount; lastLitEnd = IEnd; } } else{ //现有L太脏,全输出 bitmap.push_back(lastLit); bitmap.push_back(lit); lastLitStart = lastLitEnd; } } else{ // 得到L,F,L if(IEnd - ICount < 4){ //现有L可能被压缩 int n = ((_lzcnt_u32(FillCount) - 5)/5) + 1; if(IEnd - ICount + lastLitEnd - lastLitStart < n){ // LFL可以生成 FillCount |= (lastLitEnd - lastLitStart) << 29; FillCount |= (IEnd - ICount) << 27; for(vector<int>::const_iterator itr = lastLitStart;itr < lastLitEnd;itr++){ FillCount |= (*itr%31) << (22 - 5*(itr - lastLitStart)) ; } int countStart = ICount - lastLitEnd + lastLitStart - v.begin(); for(vector<int>::const_iterator itr = ICount;itr < IEnd;itr++){ FillCount |= (*itr%31) << (22 - 5*(itr - v.begin() - countStart)) ; } bitmap.push_back(FillCount); lastLitStart = lastLitEnd; } else if(lastLitEnd - lastLitStart < n){ // LF 可以生成 FillCount |= (lastLitEnd - lastLitStart) << 29; for(vector<int>::const_iterator itr = lastLitStart;itr < lastLitEnd;itr++){ FillCount |= (*itr%31) << (22 - 5*(itr - lastLitStart)) ; } bitmap.push_back(FillCount); lastLitStart = ICount; lastLitEnd = IEnd; lastLit = lit; } else if(IEnd - ICount < n){ //FL可以生成 bitmap.push_back(lastLit); FillCount |= (IEnd - ICount) << 27; for(vector<int>::const_iterator itr = ICount;itr < IEnd;itr++){ FillCount |= (*itr%31) << (22 - 5*(itr - ICount)) ; } bitmap.push_back(FillCount); lastLitStart = lastLitEnd; } else{ //都不能生成 bitmap.push_back(lastLit); bitmap.push_back(FillCount); lastLit = lit; lastLitStart = ICount; lastLitEnd = IEnd; } } else{ //现有L太脏 bitmap.push_back(lastLit); bitmap.push_back(FillCount); bitmap.push_back(lit); lastLitStart = lastLitEnd; } } } CCount = litCCount + 1; ICount = IEnd; } if(lastLitStart != lastLitEnd){ bitmap.push_back(lastLit); } }