void process_bin_file(char *file_name) { int seq = 0; FILE *fp = fopen(file_name, "rb"); if (!fp) { abort_("[read_bin_file] File %s cound not be opened for reading", file_name); } fseek(fp, 0, SEEK_END); long file_size = ftell(fp); if (file_size % BLOCK_SIZE) { abort_("[read_bin_file] File %s bad size", file_name); } fseek(fp, 0, SEEK_SET); Block block; block.resize(BLOCK_SIZE); BlockList blockList; for (int i=0; i<file_size/BLOCK_SIZE; ++i) { if (BLOCK_SIZE != fread(&(block.front()), 1, BLOCK_SIZE, fp)) { abort_("[read_bin_file] Fild %s read error", file_name); } if (0 == memcmp(&block.front(), FCC_TEX1, 4)) { if (!blockList.empty()) { ostringstream bc_file_name; bc_file_name << file_name << "-" << seq << ".bc"; write_bc_file(blockList, bc_file_name.str()); seq ++; blockList.clear(); } blockList.push_back(block); } else { blockList.push_back(block); } } fclose(fp); cout << "Done" << endl; }
bool ExtractContracts::runOnModule(Module &M) { bool modified = false; std::vector<Function*> Fs; std::vector<Function*> newFs; for (Function &F : M) if (!F.isDeclaration()) Fs.push_back(&F); for (auto F : Fs) { BlockList contractBlocks; LoopMap invariantBlocks; auto& LI = getAnalysis<LoopInfoWrapperPass>(*F).getLoopInfo(); std::tie(contractBlocks, invariantBlocks) = splitContractBlocks(*F, LI); if (!contractBlocks.empty() || !invariantBlocks.empty()) { DEBUG(errs() << "function " << F->getName() << " after splitting: " << *F << "\n"); modified = true; } if (!contractBlocks.empty()) { auto *newF = CodeExtractor(contractBlocks).extractCodeRegion(); std::vector<CallInst*> Is; for (auto V : newF->users()) if (auto I = dyn_cast<CallInst>(V)) Is.push_back(I); for (auto I : Is) { IRBuilder<> Builder(I); // insert one contract invocation per invocation in the original function for (auto Fs : getContractExprs(*newF)) { std::vector<Value*> Args; for (auto &A : I->arg_operands()) Args.push_back(A); auto *E = Builder.CreateCall(std::get<1>(Fs), Args); Builder.CreateCall(std::get<0>(Fs), {E}); newFs.push_back(std::get<1>(Fs)); } I->eraseFromParent(); } newF->eraseFromParent(); DEBUG(errs() << "function " << F->getName() << " after contract extraction: " << *F << "\n"); } for (auto const & entry : invariantBlocks) { auto BBs = entry.second; auto *newF = CodeExtractor(BBs).extractCodeRegion(); std::vector<CallInst*> Is; for (auto V : newF->users()) if (auto I = dyn_cast<CallInst>(V)) Is.push_back(I); for (auto I : Is) { IRBuilder<> Builder(I); // insert one invariant invocation per invocation in the original loop for (auto Fs : getContractExprs(*newF)) { std::vector<Value*> Args; for (auto &A : I->arg_operands()) Args.push_back(A); auto *E = Builder.CreateCall(std::get<1>(Fs), Args); Builder.CreateCall(std::get<0>(Fs), {E}); newFs.push_back(std::get<1>(Fs)); } I->eraseFromParent(); } newF->eraseFromParent(); DEBUG(errs() << "function " << F->getName() << " after invariant extraction: " << *F << "\n"); } } for (auto F : newFs) { DEBUG(errs() << "added function:" << *F); } return modified; }