本文整理汇总了C++中module::iterator::getName方法的典型用法代码示例。如果您正苦于以下问题:C++ iterator::getName方法的具体用法?C++ iterator::getName怎么用?C++ iterator::getName使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类module::iterator
的用法示例。
在下文中一共展示了iterator::getName方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: CleanupAndPrepareModules
/// Get the specified modules ready for code generator testing.
///
static void CleanupAndPrepareModules(BugDriver &BD,
std::unique_ptr<Module> &Test,
Module *Safe) {
// Clean up the modules, removing extra cruft that we don't need anymore...
Test = BD.performFinalCleanups(Test.get());
// If we are executing the JIT, we have several nasty issues to take care of.
if (!BD.isExecutingJIT()) return;
// First, if the main function is in the Safe module, we must add a stub to
// the Test module to call into it. Thus, we create a new function `main'
// which just calls the old one.
if (Function *oldMain = Safe->getFunction("main"))
if (!oldMain->isDeclaration()) {
// Rename it
oldMain->setName("llvm_bugpoint_old_main");
// Create a NEW `main' function with same type in the test module.
Function *newMain =
Function::Create(oldMain->getFunctionType(),
GlobalValue::ExternalLinkage, "main", Test.get());
// Create an `oldmain' prototype in the test module, which will
// corresponds to the real main function in the same module.
Function *oldMainProto = Function::Create(oldMain->getFunctionType(),
GlobalValue::ExternalLinkage,
oldMain->getName(), Test.get());
// Set up and remember the argument list for the main function.
std::vector<Value*> args;
for (Function::arg_iterator
I = newMain->arg_begin(), E = newMain->arg_end(),
OI = oldMain->arg_begin(); I != E; ++I, ++OI) {
I->setName(OI->getName()); // Copy argument names from oldMain
args.push_back(&*I);
}
// Call the old main function and return its result
BasicBlock *BB = BasicBlock::Create(Safe->getContext(), "entry", newMain);
CallInst *call = CallInst::Create(oldMainProto, args, "", BB);
// If the type of old function wasn't void, return value of call
ReturnInst::Create(Safe->getContext(), call, BB);
}
// The second nasty issue we must deal with in the JIT is that the Safe
// module cannot directly reference any functions defined in the test
// module. Instead, we use a JIT API call to dynamically resolve the
// symbol.
// Add the resolver to the Safe module.
// Prototype: void *getPointerToNamedFunction(const char* Name)
Constant *resolverFunc =
Safe->getOrInsertFunction("getPointerToNamedFunction",
Type::getInt8PtrTy(Safe->getContext()),
Type::getInt8PtrTy(Safe->getContext()),
(Type *)nullptr);
// Use the function we just added to get addresses of functions we need.
for (Module::iterator F = Safe->begin(), E = Safe->end(); F != E; ++F) {
if (F->isDeclaration() && !F->use_empty() && &*F != resolverFunc &&
!F->isIntrinsic() /* ignore intrinsics */) {
Function *TestFn = Test->getFunction(F->getName());
// Don't forward functions which are external in the test module too.
if (TestFn && !TestFn->isDeclaration()) {
// 1. Add a string constant with its name to the global file
Constant *InitArray =
ConstantDataArray::getString(F->getContext(), F->getName());
GlobalVariable *funcName =
new GlobalVariable(*Safe, InitArray->getType(), true /*isConstant*/,
GlobalValue::InternalLinkage, InitArray,
F->getName() + "_name");
// 2. Use `GetElementPtr *funcName, 0, 0' to convert the string to an
// sbyte* so it matches the signature of the resolver function.
// GetElementPtr *funcName, ulong 0, ulong 0
std::vector<Constant*> GEPargs(2,
Constant::getNullValue(Type::getInt32Ty(F->getContext())));
Value *GEP = ConstantExpr::getGetElementPtr(InitArray->getType(),
funcName, GEPargs);
std::vector<Value*> ResolverArgs;
ResolverArgs.push_back(GEP);
// Rewrite uses of F in global initializers, etc. to uses of a wrapper
// function that dynamically resolves the calls to F via our JIT API
if (!F->use_empty()) {
// Create a new global to hold the cached function pointer.
Constant *NullPtr = ConstantPointerNull::get(F->getType());
GlobalVariable *Cache =
new GlobalVariable(*F->getParent(), F->getType(),
false, GlobalValue::InternalLinkage,
NullPtr,F->getName()+".fpcache");
// Construct a new stub function that will re-route calls to F
FunctionType *FuncTy = F->getFunctionType();
Function *FuncWrapper = Function::Create(FuncTy,
GlobalValue::InternalLinkage,
F->getName() + "_wrapper",
F->getParent());
//.........这里部分代码省略.........
示例2: runOnModule
bool SpBasicBlockInstrumenter::runOnModule(Module &M) {
cerr << "instrument: --- Basic Block Spectrum ---\n";
Function *Main = M.getFunction("main");
LLVMContext &C = M.getContext();
if (Main == 0) {
cerr << "WARNING: cannot insert block instrumentation into a module"
<< " with no main function!\n";
return false; // No main, no instrumentation!
}
// Add library function prototype
Constant *SpFn = M.getOrInsertFunction("_updateSpectrum",
Type::getVoidTy(C),
Type::getInt32Ty(C), // spectrum index
Type::getInt32Ty(C), // component index
NULL);
unsigned spectrumIndex = IndexManager::getSpectrumIndex();
unsigned nComponents = 0;
// Loop through all functions within module
for (Module::iterator F = M.begin(), ME = M.end(); F != ME; ++F) {
// skip function declarations
if(F->isDeclaration())
continue;
// skip the _registerAll function
if(F->getName()=="_registerAll")
continue;
// Loop through all basic blocks within function
for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
//skip dead blocks
//is this really safe??
BasicBlock *bb = B;
if (B!=F->begin() && (pred_begin(bb)==pred_end(bb))) continue; //skip dead blocks
// Loop through all instructions within basic block
for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE; I++) {
if(isa<DbgStopPointInst>(*I)) {
DbgStopPointInst &DSPI = cast<DbgStopPointInst>(*I);
std::string file, dir, name="-";
llvm::GetConstantStringInfo(DSPI.getDirectory(), dir);
llvm::GetConstantStringInfo(DSPI.getFileName(), file);
int line = DSPI.getLine();
// add source context of this invariant to context file
ContextManager::addSpectrumContext(
spectrumIndex, // spectrumIndex
nComponents, // componentIndex
dir, // path
file, // file
line, // line
name); // name
// add call to lib function
std::vector<Value*> Args(2);
Args[0] = ConstantInt::get(Type::getInt32Ty(C), spectrumIndex);
Args[1] = ConstantInt::get(Type::getInt32Ty(C), nComponents++);
CallInst::Create(SpFn, Args.begin(), Args.end(), "", I);
break;
}
}
}
}
// add the registration of the instrumented spectrum points in the _registerAll() function
addSpectrumRegistration(M, spectrumIndex, nComponents, "Basic_Blocks");
llvm::cerr << "instrument: " << nComponents << " basic blocks instrumented\n";
// notify change of program
return true;
}
示例3: ExtractLoops
/// Given a reduced list of functions that still exposed the bug, check to see
/// if we can extract the loops in the region without obscuring the bug. If so,
/// it reduces the amount of code identified.
///
static bool ExtractLoops(BugDriver &BD,
bool (*TestFn)(BugDriver &, std::unique_ptr<Module>,
std::unique_ptr<Module>, std::string &),
std::vector<Function *> &MiscompiledFunctions,
std::string &Error) {
bool MadeChange = false;
while (1) {
if (BugpointIsInterrupted) return MadeChange;
ValueToValueMapTy VMap;
std::unique_ptr<Module> ToNotOptimize = CloneModule(BD.getProgram(), VMap);
Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize.get(),
MiscompiledFunctions, VMap)
.release();
std::unique_ptr<Module> ToOptimizeLoopExtracted =
BD.extractLoop(ToOptimize);
if (!ToOptimizeLoopExtracted) {
// If the loop extractor crashed or if there were no extractible loops,
// then this chapter of our odyssey is over with.
delete ToOptimize;
return MadeChange;
}
errs() << "Extracted a loop from the breaking portion of the program.\n";
// Bugpoint is intentionally not very trusting of LLVM transformations. In
// particular, we're not going to assume that the loop extractor works, so
// we're going to test the newly loop extracted program to make sure nothing
// has broken. If something broke, then we'll inform the user and stop
// extraction.
AbstractInterpreter *AI = BD.switchToSafeInterpreter();
bool Failure;
std::unique_ptr<Module> New =
testMergedProgram(BD, std::move(ToOptimizeLoopExtracted),
std::move(ToNotOptimize), Error, Failure);
if (!New)
return false;
// Delete the original and set the new program.
Module *Old = BD.swapProgramIn(New.release());
for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i)
MiscompiledFunctions[i] = cast<Function>(VMap[MiscompiledFunctions[i]]);
delete Old;
if (Failure) {
BD.switchToInterpreter(AI);
// Merged program doesn't work anymore!
errs() << " *** ERROR: Loop extraction broke the program. :("
<< " Please report a bug!\n";
errs() << " Continuing on with un-loop-extracted version.\n";
BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-tno.bc",
ToNotOptimize.get());
BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-to.bc",
ToOptimize);
BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-to-le.bc",
ToOptimizeLoopExtracted.get());
errs() << "Please submit the "
<< OutputPrefix << "-loop-extract-fail-*.bc files.\n";
delete ToOptimize;
return MadeChange;
}
delete ToOptimize;
BD.switchToInterpreter(AI);
outs() << " Testing after loop extraction:\n";
// Clone modules, the tester function will free them.
std::unique_ptr<Module> TOLEBackup =
CloneModule(ToOptimizeLoopExtracted.get(), VMap);
std::unique_ptr<Module> TNOBackup = CloneModule(ToNotOptimize.get(), VMap);
for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i)
MiscompiledFunctions[i] = cast<Function>(VMap[MiscompiledFunctions[i]]);
Failure = TestFn(BD, std::move(ToOptimizeLoopExtracted),
std::move(ToNotOptimize), Error);
if (!Error.empty())
return false;
ToOptimizeLoopExtracted = std::move(TOLEBackup);
ToNotOptimize = std::move(TNOBackup);
if (!Failure) {
outs() << "*** Loop extraction masked the problem. Undoing.\n";
// If the program is not still broken, then loop extraction did something
// that masked the error. Stop loop extraction now.
std::vector<std::pair<std::string, FunctionType*> > MisCompFunctions;
for (Function *F : MiscompiledFunctions) {
MisCompFunctions.emplace_back(F->getName(), F->getFunctionType());
}
if (Linker::linkModules(*ToNotOptimize,
std::move(ToOptimizeLoopExtracted)))
//.........这里部分代码省略.........
示例4: ExtractBlocks
/// Given a reduced list of functions that still expose the bug, extract as many
/// basic blocks from the region as possible without obscuring the bug.
///
static bool ExtractBlocks(BugDriver &BD,
bool (*TestFn)(BugDriver &, std::unique_ptr<Module>,
std::unique_ptr<Module>,
std::string &),
std::vector<Function *> &MiscompiledFunctions,
std::string &Error) {
if (BugpointIsInterrupted) return false;
std::vector<BasicBlock*> Blocks;
for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i)
for (BasicBlock &BB : *MiscompiledFunctions[i])
Blocks.push_back(&BB);
// Use the list reducer to identify blocks that can be extracted without
// obscuring the bug. The Blocks list will end up containing blocks that must
// be retained from the original program.
unsigned OldSize = Blocks.size();
// Check to see if all blocks are extractible first.
bool Ret = ReduceMiscompiledBlocks(BD, TestFn, MiscompiledFunctions)
.TestFuncs(std::vector<BasicBlock*>(), Error);
if (!Error.empty())
return false;
if (Ret) {
Blocks.clear();
} else {
ReduceMiscompiledBlocks(BD, TestFn,
MiscompiledFunctions).reduceList(Blocks, Error);
if (!Error.empty())
return false;
if (Blocks.size() == OldSize)
return false;
}
ValueToValueMapTy VMap;
Module *ProgClone = CloneModule(BD.getProgram(), VMap).release();
Module *ToExtract =
SplitFunctionsOutOfModule(ProgClone, MiscompiledFunctions, VMap)
.release();
std::unique_ptr<Module> Extracted =
BD.extractMappedBlocksFromModule(Blocks, ToExtract);
if (!Extracted) {
// Weird, extraction should have worked.
errs() << "Nondeterministic problem extracting blocks??\n";
delete ProgClone;
delete ToExtract;
return false;
}
// Otherwise, block extraction succeeded. Link the two program fragments back
// together.
delete ToExtract;
std::vector<std::pair<std::string, FunctionType*> > MisCompFunctions;
for (Module::iterator I = Extracted->begin(), E = Extracted->end();
I != E; ++I)
if (!I->isDeclaration())
MisCompFunctions.emplace_back(I->getName(), I->getFunctionType());
if (Linker::linkModules(*ProgClone, std::move(Extracted)))
exit(1);
// Set the new program and delete the old one.
BD.setNewProgram(ProgClone);
// Update the list of miscompiled functions.
MiscompiledFunctions.clear();
for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) {
Function *NewF = ProgClone->getFunction(MisCompFunctions[i].first);
assert(NewF && "Function not found??");
MiscompiledFunctions.push_back(NewF);
}
return true;
}
示例5: writeIStats
void StatsTracker::writeIStats() {
Module *m = executor.kmodule->module;
uint64_t istatsMask = 0;
llvm::raw_fd_ostream &of = *istatsFile;
// We assume that we didn't move the file pointer
unsigned istatsSize = of.tell();
of.seek(0);
of << "version: 1\n";
of << "creator: klee\n";
of << "pid: " << getpid() << "\n";
of << "cmd: " << m->getModuleIdentifier() << "\n\n";
of << "\n";
StatisticManager &sm = *theStatisticManager;
unsigned nStats = sm.getNumStatistics();
// Max is 13, sadly
istatsMask |= 1<<sm.getStatisticID("Queries");
istatsMask |= 1<<sm.getStatisticID("QueriesValid");
istatsMask |= 1<<sm.getStatisticID("QueriesInvalid");
istatsMask |= 1<<sm.getStatisticID("QueryTime");
istatsMask |= 1<<sm.getStatisticID("ResolveTime");
istatsMask |= 1<<sm.getStatisticID("Instructions");
istatsMask |= 1<<sm.getStatisticID("InstructionTimes");
istatsMask |= 1<<sm.getStatisticID("InstructionRealTimes");
istatsMask |= 1<<sm.getStatisticID("Forks");
istatsMask |= 1<<sm.getStatisticID("CoveredInstructions");
istatsMask |= 1<<sm.getStatisticID("UncoveredInstructions");
istatsMask |= 1<<sm.getStatisticID("States");
istatsMask |= 1<<sm.getStatisticID("MinDistToUncovered");
of << "positions: instr line\n";
for (unsigned i=0; i<nStats; i++) {
if (istatsMask & (1<<i)) {
Statistic &s = sm.getStatistic(i);
of << "event: " << s.getShortName() << " : "
<< s.getName() << "\n";
}
}
of << "events: ";
for (unsigned i=0; i<nStats; i++) {
if (istatsMask & (1<<i))
of << sm.getStatistic(i).getShortName() << " ";
}
of << "\n";
// set state counts, decremented after we process so that we don't
// have to zero all records each time.
if (istatsMask & (1<<stats::states.getID()))
updateStateStatistics(1);
std::string sourceFile = "";
CallSiteSummaryTable callSiteStats;
if (UseCallPaths)
callPathManager.getSummaryStatistics(callSiteStats);
of << "ob=" << objectFilename << "\n";
for (Module::iterator fnIt = m->begin(), fn_ie = m->end();
fnIt != fn_ie; ++fnIt) {
if (!fnIt->isDeclaration()) {
// Always try to write the filename before the function name, as otherwise
// KCachegrind can create two entries for the function, one with an
// unnamed file and one without.
const InstructionInfo &ii = executor.kmodule->infos->getFunctionInfo(fnIt);
if (ii.file != sourceFile) {
of << "fl=" << ii.file << "\n";
sourceFile = ii.file;
}
of << "fn=" << fnIt->getName().str() << "\n";
for (Function::iterator bbIt = fnIt->begin(), bb_ie = fnIt->end();
bbIt != bb_ie; ++bbIt) {
for (BasicBlock::iterator it = bbIt->begin(), ie = bbIt->end();
it != ie; ++it) {
Instruction *instr = &*it;
const InstructionInfo &ii = executor.kmodule->infos->getInfo(instr);
unsigned index = ii.id;
if (ii.file!=sourceFile) {
of << "fl=" << ii.file << "\n";
sourceFile = ii.file;
}
of << ii.assemblyLine << " ";
of << ii.line << " ";
for (unsigned i=0; i<nStats; i++)
if (istatsMask&(1<<i))
of << sm.getIndexedValue(sm.getStatistic(i), index) << " ";
of << "\n";
if (UseCallPaths &&
(isa<CallInst>(instr) || isa<InvokeInst>(instr))) {
CallSiteSummaryTable::iterator it = callSiteStats.find(instr);
if (it!=callSiteStats.end()) {
for (std::map<llvm::Function*, CallSiteInfo>::iterator
//.........这里部分代码省略.........
示例6: main
int main(int argc, char **argv) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
PrettyStackTraceProgram X(argc, argv);
LLVMContext &Context = getGlobalContext();
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
cl::ParseCommandLineOptions(argc, argv, "llvm extractor\n");
// Use lazy loading, since we only care about selected global values.
SMDiagnostic Err;
std::auto_ptr<Module> M;
M.reset(getLazyIRFileModule(InputFilename, Err, Context));
if (M.get() == 0) {
Err.Print(argv[0], errs());
return 1;
}
// Use SetVector to avoid duplicates.
SetVector<GlobalValue *> GVs;
// Figure out which globals we should extract.
for (size_t i = 0, e = ExtractGlobals.size(); i != e; ++i) {
GlobalValue *GV = M.get()->getNamedGlobal(ExtractGlobals[i]);
if (!GV) {
errs() << argv[0] << ": program doesn't contain global named '"
<< ExtractGlobals[i] << "'!\n";
return 1;
}
GVs.insert(GV);
}
// Extract globals via regular expression matching.
for (size_t i = 0, e = ExtractRegExpGlobals.size(); i != e; ++i) {
std::string Error;
Regex RegEx(ExtractRegExpGlobals[i]);
if (!RegEx.isValid(Error)) {
errs() << argv[0] << ": '" << ExtractRegExpGlobals[i] << "' "
"invalid regex: " << Error;
}
bool match = false;
for (Module::global_iterator GV = M.get()->global_begin(),
E = M.get()->global_end(); GV != E; GV++) {
if (RegEx.match(GV->getName())) {
GVs.insert(&*GV);
match = true;
}
}
if (!match) {
errs() << argv[0] << ": program doesn't contain global named '"
<< ExtractRegExpGlobals[i] << "'!\n";
return 1;
}
}
// Figure out which functions we should extract.
for (size_t i = 0, e = ExtractFuncs.size(); i != e; ++i) {
GlobalValue *GV = M.get()->getFunction(ExtractFuncs[i]);
if (!GV) {
errs() << argv[0] << ": program doesn't contain function named '"
<< ExtractFuncs[i] << "'!\n";
return 1;
}
GVs.insert(GV);
}
// Extract functions via regular expression matching.
for (size_t i = 0, e = ExtractRegExpFuncs.size(); i != e; ++i) {
std::string Error;
StringRef RegExStr = ExtractRegExpFuncs[i];
Regex RegEx(RegExStr);
if (!RegEx.isValid(Error)) {
errs() << argv[0] << ": '" << ExtractRegExpFuncs[i] << "' "
"invalid regex: " << Error;
}
bool match = false;
for (Module::iterator F = M.get()->begin(), E = M.get()->end(); F != E;
F++) {
if (RegEx.match(F->getName())) {
GVs.insert(&*F);
match = true;
}
}
if (!match) {
errs() << argv[0] << ": program doesn't contain global named '"
<< ExtractRegExpFuncs[i] << "'!\n";
return 1;
}
}
// Materialize requisite global values.
if (!DeleteFn)
for (size_t i = 0, e = GVs.size(); i != e; ++i) {
GlobalValue *GV = GVs[i];
if (GV->isMaterializable()) {
std::string ErrInfo;
if (GV->Materialize(&ErrInfo)) {
errs() << argv[0] << ": error reading input: " << ErrInfo << "\n";
return 1;
}
//.........这里部分代码省略.........
示例7: if
/// Based on GetAllUndefinedSymbols() from LLVM3.2
///
/// GetAllUndefinedSymbols - calculates the set of undefined symbols that still
/// exist in an LLVM module. This is a bit tricky because there may be two
/// symbols with the same name but different LLVM types that will be resolved to
/// each other but aren't currently (thus we need to treat it as resolved).
///
/// Inputs:
/// M - The module in which to find undefined symbols.
///
/// Outputs:
/// UndefinedSymbols - A set of C++ strings containing the name of all
/// undefined symbols.
///
static void
GetAllUndefinedSymbols(Module *M, std::set<std::string> &UndefinedSymbols) {
static const std::string llvmIntrinsicPrefix="llvm.";
std::set<std::string> DefinedSymbols;
UndefinedSymbols.clear();
KLEE_DEBUG_WITH_TYPE("klee_linker",
dbgs() << "*** Computing undefined symbols ***\n");
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
if (I->hasName()) {
if (I->isDeclaration())
UndefinedSymbols.insert(I->getName());
else if (!I->hasLocalLinkage()) {
#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5)
assert(!I->hasDLLImportLinkage() && "Found dllimported non-external symbol!");
#else
assert(!I->hasDLLImportStorageClass() && "Found dllimported non-external symbol!");
#endif
DefinedSymbols.insert(I->getName());
}
}
for (Module::global_iterator I = M->global_begin(), E = M->global_end();
I != E; ++I)
if (I->hasName()) {
if (I->isDeclaration())
UndefinedSymbols.insert(I->getName());
else if (!I->hasLocalLinkage()) {
#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5)
assert(!I->hasDLLImportLinkage() && "Found dllimported non-external symbol!");
#else
assert(!I->hasDLLImportStorageClass() && "Found dllimported non-external symbol!");
#endif
DefinedSymbols.insert(I->getName());
}
}
for (Module::alias_iterator I = M->alias_begin(), E = M->alias_end();
I != E; ++I)
if (I->hasName())
DefinedSymbols.insert(I->getName());
// Prune out any defined symbols from the undefined symbols set
// and other symbols we don't want to treat as an undefined symbol
std::vector<std::string> SymbolsToRemove;
for (std::set<std::string>::iterator I = UndefinedSymbols.begin();
I != UndefinedSymbols.end(); ++I )
{
if (DefinedSymbols.count(*I))
{
SymbolsToRemove.push_back(*I);
continue;
}
// Strip out llvm intrinsics
if ( (I->size() >= llvmIntrinsicPrefix.size() ) &&
(I->compare(0, llvmIntrinsicPrefix.size(), llvmIntrinsicPrefix) == 0) )
{
KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "LLVM intrinsic " << *I <<
" has will be removed from undefined symbols"<< "\n");
SymbolsToRemove.push_back(*I);
continue;
}
// Symbol really is undefined
KLEE_DEBUG_WITH_TYPE("klee_linker",
dbgs() << "Symbol " << *I << " is undefined.\n");
}
// Remove KLEE intrinsics from set of undefined symbols
for (SpecialFunctionHandler::const_iterator sf = SpecialFunctionHandler::begin(),
se = SpecialFunctionHandler::end(); sf != se; ++sf)
{
if (UndefinedSymbols.find(sf->name) == UndefinedSymbols.end())
continue;
SymbolsToRemove.push_back(sf->name);
KLEE_DEBUG_WITH_TYPE("klee_linker",
dbgs() << "KLEE intrinsic " << sf->name <<
" has will be removed from undefined symbols"<< "\n");
}
// Now remove the symbols from undefined set.
for (size_t i = 0, j = SymbolsToRemove.size(); i < j; ++i )
UndefinedSymbols.erase(SymbolsToRemove[i]);
//.........这里部分代码省略.........
示例8: runOnModuleInternal
bool BUDataStructures::runOnModuleInternal(Module& M) {
std::vector<const Function*> Stack;
hash_map<const Function*, unsigned> ValMap;
unsigned NextID = 1;
Function *MainFunc = M.getFunction("main");
if (MainFunc && !MainFunc->isDeclaration()) {
calculateGraphs(MainFunc, Stack, NextID, ValMap);
CloneAuxIntoGlobal(getDSGraph(MainFunc));
} else {
DEBUG(errs() << debugname << ": No 'main' function found!\n");
}
// Calculate the graphs for any functions that are unreachable from main...
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
if (!I->isDeclaration() && !hasDSGraph(I)) {
if (MainFunc)
DEBUG(errs() << debugname << ": Function unreachable from main: "
<< I->getName() << "\n");
calculateGraphs(I, Stack, NextID, ValMap); // Calculate all graphs.
CloneAuxIntoGlobal(getDSGraph(I));
}
// If we computed any temporary indcallgraphs, free them now.
for (std::map<std::vector<const Function*>,
std::pair<DSGraph*, std::vector<DSNodeHandle> > >::iterator I =
IndCallGraphMap.begin(), E = IndCallGraphMap.end(); I != E; ++I) {
I->second.second.clear(); // Drop arg refs into the graph.
delete I->second.first;
}
IndCallGraphMap.clear();
// At the end of the bottom-up pass, the globals graph becomes complete.
// FIXME: This is not the right way to do this, but it is sorta better than
// nothing! In particular, externally visible globals and unresolvable call
// nodes at the end of the BU phase should make things that they point to
// incomplete in the globals graph.
//
finalizeGlobals();
GlobalsGraph->removeTriviallyDeadNodes(true);
GlobalsGraph->maskIncompleteMarkers();
// Mark external globals incomplete.
GlobalsGraph->markIncompleteNodes(DSGraph::IgnoreGlobals);
formGlobalECs();
// Merge the globals variables (not the calls) from the globals graph back
// into the main function's graph so that the main function contains all of
// the information about global pools and GV usage in the program.
if (MainFunc && !MainFunc->isDeclaration()) {
DSGraph* MainGraph = getDSGraph(MainFunc);
const DSGraph* GG = MainGraph->getGlobalsGraph();
ReachabilityCloner RC(MainGraph, GG,
DSGraph::DontCloneCallNodes |
DSGraph::DontCloneAuxCallNodes);
// Clone the global nodes into this graph.
for (DSScalarMap::global_iterator I = GG->getScalarMap().global_begin(),
E = GG->getScalarMap().global_end(); I != E; ++I)
if (isa<GlobalVariable>(*I))
RC.getClonedNH(GG->getNodeForValue(*I));
MainGraph->maskIncompleteMarkers();
MainGraph->markIncompleteNodes(DSGraph::MarkFormalArgs |
DSGraph::IgnoreGlobals);
}
NumCallEdges += callee.size();
return false;
}
示例9: linker
Module *klee::linkWithLibrary(Module *module,
const std::string &libraryName,
std::set<std::string>* kleeFunctions,
std::set<std::string>* intrinsicFunctions) {
DEBUG_WITH_TYPE("klee_linker", dbgs() << "Linking file " << libraryName << "\n");
#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 3)
if (!sys::fs::exists(libraryName)) {
klee_error("Link with library %s failed. No such file.",
libraryName.c_str());
}
OwningPtr<MemoryBuffer> Buffer;
if (error_code ec = MemoryBuffer::getFile(libraryName,Buffer)) {
klee_error("Link with library %s failed: %s", libraryName.c_str(),
ec.message().c_str());
}
sys::fs::file_magic magic = sys::fs::identify_magic(Buffer->getBuffer());
LLVMContext &Context = getGlobalContext();
std::string ErrorMessage;
if (magic == sys::fs::file_magic::bitcode) {
Module *Result = 0;
Result = ParseBitcodeFile(Buffer.get(), Context, &ErrorMessage);
if (!Result || Linker::LinkModules(module, Result, Linker::DestroySource,
&ErrorMessage))
klee_error("Link with library %s failed: %s", libraryName.c_str(),
ErrorMessage.c_str());
if (kleeFunctions && intrinsicFunctions) {
for (Module::iterator fi = Result->begin(), fe = Result->end(); fi != fe; fi++) {
std::string functionName = fi->getName().str();
if (fi->getName().startswith("klee") || fi->getName().startswith("llvm")) {
kleeFunctions->insert(functionName);
} else {
intrinsicFunctions->insert(functionName);
}
}
}
delete Result;
} else if (magic == sys::fs::file_magic::archive) {
OwningPtr<object::Binary> arch;
if (error_code ec = object::createBinary(Buffer.take(), arch))
klee_error("Link with library %s failed: %s", libraryName.c_str(),
ec.message().c_str());
if (object::Archive *a = dyn_cast<object::Archive>(arch.get())) {
// Handle in helper
if (!linkBCA(a, module, ErrorMessage))
klee_error("Link with library %s failed: %s", libraryName.c_str(),
ErrorMessage.c_str());
}
else {
klee_error("Link with library %s failed: Cast to archive failed", libraryName.c_str());
}
} else if (magic.is_object()) {
OwningPtr<object::Binary> obj;
if (object::ObjectFile *o = dyn_cast<object::ObjectFile>(obj.get())) {
klee_warning("Link with library: Object file %s in archive %s found. "
"Currently not supported.",
o->getFileName().data(), libraryName.c_str());
}
} else {
klee_error("Link with library %s failed: Unrecognized file type.",
libraryName.c_str());
}
return module;
#else
Linker linker("klee", module, false);
llvm::sys::Path libraryPath(libraryName);
bool native = false;
if (linker.LinkInFile(libraryPath, native)) {
klee_error("Linking library %s failed", libraryName.c_str());
}
return linker.releaseModule();
#endif
}
示例10: runOnModule
bool InternalizePass::runOnModule(Module &M) {
CallGraph *CG = getAnalysisIfAvailable<CallGraph>();
CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : 0;
bool Changed = false;
// Never internalize functions which code-gen might insert.
// FIXME: We should probably add this (and the __stack_chk_guard) via some
// type of call-back in CodeGen.
ExternalNames.insert("__stack_chk_fail");
// Mark all functions not in the api as internal.
// FIXME: maybe use private linkage?
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
if (!I->isDeclaration() && // Function must be defined here
// Available externally is really just a "declaration with a body".
!I->hasAvailableExternallyLinkage() &&
!I->hasLocalLinkage() && // Can't already have internal linkage
!ExternalNames.count(I->getName())) {// Not marked to keep external?
I->setLinkage(GlobalValue::InternalLinkage);
// Remove a callgraph edge from the external node to this function.
if (ExternalNode) ExternalNode->removeOneAbstractEdgeTo((*CG)[I]);
Changed = true;
++NumFunctions;
DEBUG(dbgs() << "Internalizing func " << I->getName() << "\n");
}
// Never internalize the llvm.used symbol. It is used to implement
// attribute((used)).
// FIXME: Shouldn't this just filter on llvm.metadata section??
ExternalNames.insert("llvm.used");
ExternalNames.insert("llvm.compiler.used");
// Never internalize anchors used by the machine module info, else the info
// won't find them. (see MachineModuleInfo.)
ExternalNames.insert("llvm.global_ctors");
ExternalNames.insert("llvm.global_dtors");
ExternalNames.insert("llvm.global.annotations");
// Never internalize symbols code-gen inserts.
ExternalNames.insert("__stack_chk_guard");
// Mark all global variables with initializers that are not in the api as
// internal as well.
// FIXME: maybe use private linkage?
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I)
if (!I->isDeclaration() && !I->hasLocalLinkage() &&
// Available externally is really just a "declaration with a body".
!I->hasAvailableExternallyLinkage() &&
!ExternalNames.count(I->getName())) {
I->setLinkage(GlobalValue::InternalLinkage);
Changed = true;
++NumGlobals;
DEBUG(dbgs() << "Internalized gvar " << I->getName() << "\n");
}
// Mark all aliases that are not in the api as internal as well.
for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
I != E; ++I)
if (!I->isDeclaration() && !I->hasInternalLinkage() &&
// Available externally is really just a "declaration with a body".
!I->hasAvailableExternallyLinkage() &&
!ExternalNames.count(I->getName())) {
I->setLinkage(GlobalValue::InternalLinkage);
Changed = true;
++NumAliases;
DEBUG(dbgs() << "Internalized alias " << I->getName() << "\n");
}
return Changed;
}
示例11: runOnModule
bool InvLoadInstrumenter::runOnModule(Module &M) {
Function *Main = M.getFunction("main");
LLVMContext &C = M.getContext();
cerr << "instrument: --- Load Invariant ---\n";
if (Main == 0) {
cerr << "WARNING: cannot insert load instrumentation into a module"
<< " with no main function!\n";
return false; // No main, no instrumentation!
}
// Add library function prototypes
Constant *LoadDoubleFn = M.getOrInsertFunction("_handleInvariantChangeDouble",
Type::getVoidTy(C), // returns void
Type::getInt32Ty(C), // invTypeIndex
Type::getInt32Ty(C), // invIndex
Type::getDoubleTy(C), // val
NULL);
Constant *LoadIntegerFn = M.getOrInsertFunction("_handleInvariantChangeInt",
Type::getVoidTy(C), // returns void
Type::getInt32Ty(C), // invTypeIndex
Type::getInt32Ty(C), // invIndex
Type::getInt32Ty(C), // val
NULL);
Constant *LoadPointerFn = M.getOrInsertFunction("_handleInvariantChangePtr",
Type::getVoidTy(C), // returns void
Type::getInt32Ty(C), // invTypeIndex
Type::getInt32Ty(C), // invIndex
PointerType::getUnqual(Type::getInt32Ty(C)), // val
NULL);
Constant *LoadUintFn = M.getOrInsertFunction("_handleInvariantChangeUInt",
Type::getVoidTy(C), // returns void
Type::getInt32Ty(C), // invTypeIndex
Type::getInt32Ty(C), // invIndex
Type::getInt32Ty(C), // val
NULL);
TargetData targetData(&M);
unsigned int nInvariants = 0;
unsigned int invariantTypeIndex = IndexManager::getInvariantTypeIndex();
// Loop through all functions within module
for (Module::iterator F = M.begin(), ME = M.end(); F != ME; ++F) {
std::string dir="-", file="-", name="-";
int line = 0;
// skip the _registerAll function
if(F->getName()=="_registerAll")
continue;
// Loop through all basic blocks within function
for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
// Loop through all instructions within basic block
for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE; I++) {
// remember information of the last known debug stoppoint
if(isa<DbgStopPointInst>(*I)) {
DbgStopPointInst &DSPI = cast<DbgStopPointInst>(*I);
llvm::GetConstantStringInfo(DSPI.getDirectory(), dir);
llvm::GetConstantStringInfo(DSPI.getFileName(), file);
line = DSPI.getLine();
}
// Consider only load instructions
if(isa<LoadInst>(*I)) {
LoadInst &LD = cast<LoadInst>(*I);
Value *Val = LD.getOperand(0); // value to be loaded
const Type *InstType = LD.getType(); // type of loaded value
std::vector<Value*> Args(3);
// try to get name of the loaded value:
// "variableName"
// "-" if it cannot be found
if(Val->hasName()) {
name = Val->getName();
} else if(Val->getUnderlyingObject()->hasName()) {
name = Val->getUnderlyingObject()->getName();
} else {
name = "-";
}
// add source context of this invariant to context file
ContextManager::addInvariantTypeContext(
invariantTypeIndex, // invariantTypeIndex
nInvariants, // invariantIndex
dir, // path
file, // file
line, // line
name); // name
// needs to be instrumented after the value has been loaded
I++;
// insert call to correct library function,
// which depends on the type of the loaded value,
// after the current load instruction
if(InstType->isInteger()) {
Args[0] = ConstantInt::get(Type::getInt32Ty(C), invariantTypeIndex);
//.........这里部分代码省略.........
示例12: HandleQueries
void ComputeSSO::HandleQueries(Module& M)
{
for(set<QueryInput*>::iterator qit = queryinputs.begin();qit!=queryinputs.end();++qit)
{
bool constCheck;
errs()<<"\n\n\n\n*******************************************************Query ";
errs()<<"\nOperation : "<<(*qit)->operation;
errs()<<"\nConstCheck : "<<(*qit)->constcheck;
string operation = (*qit)->operation;
set<string> labels = (*qit)->labels;
set<Value*> vals = (*qit)->labVals;
std::set<GraphNode*> taintedA;
std::set<GraphNode*> taintedB;
std::set<GraphNode*> intersectGraph;
for(set<string>::iterator label = labels.begin();label != labels.end();++label)
errs()<<" - "<<*label;
errs()<<"\n*******************************************************\n ";
constCheck = (*qit)->constcheck;
if(constCheck)
{
for(set<Value*>::iterator val = vals.begin();val != vals.end();++val)
{
taintedA = taintGraphMap[*val];
}
intersectGraph = taintedA;
}
else
{
for(set<Value*>::iterator val = vals.begin();val != vals.end();++val)
{
taintedA = taintGraphMap[*val];
++val;
if(val!=vals.end())
taintedB = taintGraphMap[*val];
}
if(strcmp(operation.c_str(),"intersect")==0)
{
// intersectGraph = getIntersect(taintedA,taintedB);
for(set<GraphNode*>::iterator gnode = taintedA.begin();gnode != taintedA.end();++gnode)
{
if(taintedB.count(*gnode) > 0)
{
GraphNode* interNode = (*gnode)->clone();
intersectGraph.insert(interNode);
}
}
}
}
int branches =0;
errs()<<"\n Intersect graph size :"<<intersectGraph.size();
//print intersect graph nodes:
// PrintTainted(intersectGraph);
// for(set<GraphNode*>::iterator gnode = intersectGraph.begin();gnode != intersectGraph.end();++gnode)
// {
// errs()<<"\n Node: "<<(*gnode)->getLabel();
// }
//Print appropriate vals....:
for (Module::iterator F = M.begin(), endF = M.end(); F != endF; ++F) {
string funcName = F->getName();
// errs()<<"\nTaints in function: "<<funcName;
for (Function::iterator BB = F->begin(), endBB = F->end(); BB != endBB; ++BB) {
string bbName ="noName";
if(BB->hasName())
{
bbName = BB->getName();
}
// errs()<<" - block: "<<bbName;
for (BasicBlock::iterator I = BB->begin(), endI = BB->end(); I
!= endI; ++I) {
GraphNode* g = depGraph->findNode(I);
if (intersectGraph.count(g)) {
errs()<<"\n Node found..:";
I->dump();
errs()<<"Taint in function : "<<funcName<<" :";
I->dump();
if (BranchInst *BI = dyn_cast<BranchInst>(I))
{
if(constCheck)
{
Value* conditional = BI->getCondition();
for (unsigned int i = 0; i < cast<User> (conditional)->getNumOperands(); i++)
{
//.........这里部分代码省略.........
示例13: runOnModule
// Entry point of the module
bool PrepareCSI::runOnModule(Module &M){
vector<pair<string, set<set<string> > > > schemeData;
if(VariantsFile.empty()){
outs() << "Reading stdin for instrumentation scheme...\n";
schemeData = readScheme(cin);
outs() << "Finished reading stdin for scheme\n";
}
else{
ifstream inFile(VariantsFile.c_str(), ios::in);
if(!inFile || !inFile.is_open())
report_fatal_error("cannot open specified instrumentation scheme file: " +
VariantsFile);
schemeData = readScheme(inFile);
}
DEBUG(printScheme(schemeData));
// verify that all passes provided exist
DEBUG(dbgs() << "verifying...\n");
verifyScheme(schemeData);
DEBUG(printScheme(schemeData));
Context = &M.getContext();
// Find the matching pattern for each function
map<Function*, set<set<string> >*> matches;
for(Module::iterator F = M.begin(), E = M.end(); F != E; ++F){
if(F->isDeclaration() || F->isIntrinsic())
continue;
bool found = false;
for(vector<pair<string, set<set<string> > > >::iterator i = schemeData.begin(), e = schemeData.end(); i != e; ++i){
if(patternMatch(F->getName(), i->first)){
matches[F] = &(i->second);
found = true;
break;
}
}
if(!found){
errs() << "WARNING: No scheme match found for function '"
<< F->getName() << "'. Skipping.\n";
continue;
}
}
// Filter patterns matched to each function, and replicate
for(map<Function*, set<set<string> >*>::iterator i = matches.begin(), e = matches.end(); i != e; ++i){
Function* F = i->first;
// go through all filters for each possible scheme. if it passes all
// filters, make a replica of this function with those tags on it, and add
// that replica to the "replicas" set. else, print warning
set<const set<string>*> replicas;
for(set<set<string> >::iterator j = i->second->begin(), je = i->second->end(); j != je; ++j){
bool passed = true;
if(!NoFilter){
for(vector<FilterFn>::const_iterator fi = Filters.begin(), fe = Filters.end(); fi != fe; ++fi){
if(!(*fi)(*j, F)){
passed = false;
break;
}
}
}
if(passed)
replicas.insert(&*j);
else{
outs() << "WARNING: filtered out scheme '";
for(set<string>::iterator k = j->begin(), ke = j->end(); k != ke; ++k){
if(k != j->begin())
outs() << ",";
outs() << *k;
}
outs() << "' for function '" << F->getName().str() << "'\n";
continue;
}
}
switch (replicas.size()) {
case 0:
continue;
case 1: {
// instrument the original body (don't replicate and trampoline)
const set<string>* scheme = *(replicas.begin());
for(set<string>::iterator j = scheme->begin(), je = scheme->end(); j != je; ++j)
addInstrumentationType(*F, *j);
break;
}
default:
// if the function is variable-argument, currently don't support
if(F->isVarArg()){
outs() << "WARNING: cannot instrument variable-argument function '"
<< F->getName() << "'\n";
continue;
}
// make a function for each scheme
vector<Function*> funcReplicas;
for(set<const set<string>*>::iterator j = replicas.begin(), je = replicas.end(); j != je; ++j){
//.........这里部分代码省略.........
示例14: runOnModule
bool PoolAllocateSimple::runOnModule(Module &M) {
if (M.begin() == M.end()) return false;
//
// Get pointers to 8 and 32 bit LLVM integer types.
//
VoidType = Type::getVoidTy(M.getContext());
Int8Type = IntegerType::getInt8Ty(M.getContext());
Int32Type = IntegerType::getInt32Ty(M.getContext());
// Get the Target Data information and the Graphs
if (CompleteDSA) {
Graphs = &getAnalysis<EQTDDataStructures>();
} else {
Graphs = &getAnalysis<BasicDataStructures>();
}
assert (Graphs && "No DSA pass available!\n");
DataLayout & TD = getAnalysis<DataLayout>();
// Add the pool* prototypes to the module
AddPoolPrototypes(&M);
//
// Create a single DSGraph which contains all of the information found in all
// the DSGraphs we got from DSA. We do this because we're going to start
// making modifications to the points-to results.
//
GlobalECs = Graphs->getGlobalECs();
CombinedDSGraph = new DSGraph (GlobalECs,
TD,
Graphs->getTypeSS(),
Graphs->getGlobalsGraph());
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
if (Graphs->hasDSGraph (*I))
CombinedDSGraph->cloneInto (Graphs->getDSGraph(*I));
}
//
// Now fold all of the heap nodes in our DSGraph (i.e., make them
// type-unknown). We do this because heap nodes may change type if we
// consider the effects of dangling pointers.
//
FoldNodesInDSGraph (*CombinedDSGraph);
FoldNodesInDSGraph (*(CombinedDSGraph->getGlobalsGraph()));
//
// Create the global pool.
//
TheGlobalPool = CreateGlobalPool(1, 1, M);
//
// Now that all call targets are available, rewrite the function bodies of
// the clones.
//
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
//
// Skip functions that this pass added.
//
std::string name = I->getName();
if (name == "__poolalloc_init") continue;
if (name == PoolInit->getName().str()) continue;
//
// Skip declarations.
//
if (!(I->isDeclaration()))
ProcessFunctionBodySimple(*I, TD);
}
return true;
}
示例15: runOnModule
bool LoaderPass::runOnModule(Module &M) {
ProfileInfoLoader PIL("profile-loader", Filename);
EdgeInformation.clear();
std::vector<unsigned> Counters = PIL.getRawEdgeCounts();
if (Counters.size() > 0) {
ReadCount = 0;
for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
if (F->isDeclaration()) continue;
DEBUG(dbgs() << "Working on " << F->getName() << "\n");
readEdge(getEdge(0,&F->getEntryBlock()), Counters);
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
TerminatorInst *TI = BB->getTerminator();
for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
readEdge(getEdge(BB,TI->getSuccessor(s)), Counters);
}
}
}
if (ReadCount != Counters.size()) {
errs() << "WARNING: profile information is inconsistent with "
<< "the current program!\n";
}
NumEdgesRead = ReadCount;
}
Counters = PIL.getRawOptimalEdgeCounts();
if (Counters.size() > 0) {
ReadCount = 0;
for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
if (F->isDeclaration()) continue;
DEBUG(dbgs() << "Working on " << F->getName() << "\n");
readEdge(getEdge(0,&F->getEntryBlock()), Counters);
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
TerminatorInst *TI = BB->getTerminator();
if (TI->getNumSuccessors() == 0) {
readEdge(getEdge(BB,0), Counters);
}
for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
readEdge(getEdge(BB,TI->getSuccessor(s)), Counters);
}
}
while (SpanningTree.size() > 0) {
unsigned size = SpanningTree.size();
BBisUnvisited.clear();
for (std::set<Edge>::iterator ei = SpanningTree.begin(),
ee = SpanningTree.end(); ei != ee; ++ei) {
BBisUnvisited.insert(ei->first);
BBisUnvisited.insert(ei->second);
}
while (BBisUnvisited.size() > 0) {
recurseBasicBlock(*BBisUnvisited.begin());
}
if (SpanningTree.size() == size) {
DEBUG(dbgs()<<"{");
for (std::set<Edge>::iterator ei = SpanningTree.begin(),
ee = SpanningTree.end(); ei != ee; ++ei) {
DEBUG(dbgs()<< *ei <<",");
}
assert(0 && "No edge calculated!");
}
}
}
if (ReadCount != Counters.size()) {
errs() << "WARNING: profile information is inconsistent with "
<< "the current program!\n";
}
NumEdgesRead = ReadCount;
}
BlockInformation.clear();
Counters = PIL.getRawBlockCounts();
if (Counters.size() > 0) {
ReadCount = 0;
for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
if (F->isDeclaration()) continue;
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
if (ReadCount < Counters.size())
// Here the data realm changes from the unsigned of the file to the
// double of the ProfileInfo. This conversion is save because we know
// that everything thats representable in unsinged is also
// representable in double.
BlockInformation[F][BB] = (double)Counters[ReadCount++];
}
if (ReadCount != Counters.size()) {
errs() << "WARNING: profile information is inconsistent with "
<< "the current program!\n";
}
}
FunctionInformation.clear();
Counters = PIL.getRawFunctionCounts();
if (Counters.size() > 0) {
ReadCount = 0;
for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
if (F->isDeclaration()) continue;
if (ReadCount < Counters.size())
//.........这里部分代码省略.........