本文整理汇总了C++中Constant::isNullValue方法的典型用法代码示例。如果您正苦于以下问题:C++ Constant::isNullValue方法的具体用法?C++ Constant::isNullValue怎么用?C++ Constant::isNullValue使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Constant
的用法示例。
在下文中一共展示了Constant::isNullValue方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: getIntToPtr
/// SymbolicallyEvaluateGEP - If we can symbolically evaluate the specified GEP
/// constant expression, do so.
static Constant *SymbolicallyEvaluateGEP(Constant** Ops, unsigned NumOps,
const Type *ResultTy,
const TargetData *TD) {
Constant *Ptr = Ops[0];
if (!cast<PointerType>(Ptr->getType())->getElementType()->isSized())
return 0;
if (TD && Ptr->isNullValue()) {
// If this is a constant expr gep that is effectively computing an
// "offsetof", fold it into 'cast int Size to T*' instead of 'gep 0, 0, 12'
bool isFoldableGEP = true;
for (unsigned i = 1; i != NumOps; ++i)
if (!isa<ConstantInt>(Ops[i])) {
isFoldableGEP = false;
break;
}
if (isFoldableGEP) {
uint64_t Offset = TD->getIndexedOffset(Ptr->getType(),
(Value**)Ops+1, NumOps-1);
Constant *C = ConstantInt::get(TD->getIntPtrType(), Offset);
return ConstantExpr::getIntToPtr(C, ResultTy);
}
}
return 0;
}
示例2: runStaticConstructorsDestructors
/// runStaticConstructorsDestructors - This method is used to execute all of
/// the static constructors or destructors for a module, depending on the
/// value of isDtors.
void ExecutionEngine::runStaticConstructorsDestructors(Module *module, bool isDtors) {
const char *Name = isDtors ? "llvm.global_dtors" : "llvm.global_ctors";
// Execute global ctors/dtors for each module in the program.
GlobalVariable *GV = module->getNamedGlobal(Name);
// If this global has internal linkage, or if it has a use, then it must be
// an old-style (llvmgcc3) static ctor with __main linked in and in use. If
// this is the case, don't execute any of the global ctors, __main will do
// it.
if (!GV || GV->isDeclaration() || GV->hasLocalLinkage()) return;
// Should be an array of '{ int, void ()* }' structs. The first value is
// the init priority, which we ignore.
ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
if (!InitList) return;
for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i)
if (ConstantStruct *CS =
dyn_cast<ConstantStruct>(InitList->getOperand(i))) {
if (CS->getNumOperands() != 2) return; // Not array of 2-element structs.
Constant *FP = CS->getOperand(1);
if (FP->isNullValue())
break; // Found a null terminator, exit.
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
if (CE->isCast())
FP = CE->getOperand(0);
if (Function *F = dyn_cast<Function>(FP)) {
// Execute the ctor/dtor function!
runFunction(F, std::vector<GenericValue>());
}
}
}
示例3: instrumentMemIntrinsic
// Instrument memset/memmove/memcpy
bool AddressSanitizer::instrumentMemIntrinsic(AsanFunctionContext &AFC,
MemIntrinsic *MI) {
Value *Dst = MI->getDest();
MemTransferInst *MemTran = dyn_cast<MemTransferInst>(MI);
Value *Src = MemTran ? MemTran->getSource() : 0;
Value *Length = MI->getLength();
Constant *ConstLength = dyn_cast<Constant>(Length);
Instruction *InsertBefore = MI;
if (ConstLength) {
if (ConstLength->isNullValue()) return false;
} else {
// The size is not a constant so it could be zero -- check at run-time.
IRBuilder<> IRB(InsertBefore);
Value *Cmp = IRB.CreateICmpNE(Length,
Constant::getNullValue(Length->getType()));
InsertBefore = splitBlockAndInsertIfThen(Cmp, false);
}
instrumentMemIntrinsicParam(AFC, MI, Dst, Length, InsertBefore, true);
if (Src)
instrumentMemIntrinsicParam(AFC, MI, Src, Length, InsertBefore, false);
return true;
}
示例4: assert
/// allocateIDATA - allocate an initialized global into an existing
/// or new section and return that section.
const MCSection *
PIC16TargetObjectFile::allocateIDATA(const GlobalVariable *GV) const{
assert(GV->hasInitializer() && "This global doesn't need space");
Constant *C = GV->getInitializer();
assert(!C->isNullValue() && "initialized globals has zero initializer");
assert(GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE &&
"can allocate initialized RAM data only");
// Find how much space this global needs.
const TargetData *TD = TM->getTargetData();
const Type *Ty = C->getType();
unsigned ValSize = TD->getTypeAllocSize(Ty);
// Go through all IDATA Sections and assign this variable
// to the first available section having enough space.
PIC16Section *Found = NULL;
for (unsigned i = 0; i < IDATASections_.size(); i++) {
if (DataBankSize - IDATASections_[i]->getSize() >= ValSize) {
Found = IDATASections_[i];
break;
}
}
// No IDATA section spacious enough was found. Crate a new one.
if (!Found) {
std::string name = PAN::getIdataSectionName(IDATASections_.size());
Found = getPIC16DataSection(name.c_str(), IDATA);
}
// Insert the GV into this IDATA.
Found->Items.push_back(GV);
Found->setSize(Found->getSize() + ValSize);
return Found;
}
示例5: addTryBlockMapEntry
static void addTryBlockMapEntry(WinEHFuncInfo &FuncInfo, int TryLow,
int TryHigh, int CatchHigh,
ArrayRef<const CatchPadInst *> Handlers) {
WinEHTryBlockMapEntry TBME;
TBME.TryLow = TryLow;
TBME.TryHigh = TryHigh;
TBME.CatchHigh = CatchHigh;
assert(TBME.TryLow <= TBME.TryHigh);
for (const CatchPadInst *CPI : Handlers) {
WinEHHandlerType HT;
Constant *TypeInfo = cast<Constant>(CPI->getArgOperand(0));
if (TypeInfo->isNullValue())
HT.TypeDescriptor = nullptr;
else
HT.TypeDescriptor = cast<GlobalVariable>(TypeInfo->stripPointerCasts());
HT.Adjectives = cast<ConstantInt>(CPI->getArgOperand(1))->getZExtValue();
HT.Handler = CPI->getParent();
if (auto *AI =
dyn_cast<AllocaInst>(CPI->getArgOperand(2)->stripPointerCasts()))
HT.CatchObj.Alloca = AI;
else
HT.CatchObj.Alloca = nullptr;
TBME.HandlerArray.push_back(HT);
}
FuncInfo.TryBlockMap.push_back(TBME);
}
示例6: PatchDtorFunctions
void ControlFlowIntegrity::PatchDtorFunctions(void) {
GlobalVariable *global_dtors = _M.getNamedGlobal("llvm.global_dtors");
// check for dtor section
if (!global_dtors || !global_dtors->getOperand(0)) {
return;
}
Constant *c = global_dtors->getInitializer();
if (!c)
report_fatal_error("llvm.global_dtors without initializer!", false);
ConstantArray *CA = dyn_cast<ConstantArray>(c);
if (!CA)
report_fatal_error("Cast to ConstantArray failed", true);
for (Value *Op : ValueOpRange(*CA)) {
ConstantStruct *CS = dyn_cast<ConstantStruct>(Op);
if (!CS)
report_fatal_error("Cast to ConstantStruct failed", true);
Constant *FP = CS->getOperand(1);
if (FP->isNullValue())
break; // found a NULL termintator, stop here
Function *F = dyn_cast_or_null<Function>(FP);
if (F == NULL) {
// Strip off constant expression cast
ConstantExpr *CE = dyn_cast<ConstantExpr>(FP);
if (!CE)
report_fatal_error("Cast to ConstantExpr failed", true);
if (CE->isCast()) {
FP = CE->getOperand(0);
}
F = dyn_cast_or_null<Function>(FP);
}
if (!F)
report_fatal_error("Cast to Function failed", true);
// set visibility to hidden (do not export), unless it is already
// local (for ex. static), in which case we have to make it non-static
if (F->hasLocalLinkage()) {
F->setLinkage(llvm::GlobalValue::ExternalLinkage);
}
F->setVisibility(GlobalValue::HiddenVisibility);
_FiniFunctions.insert(F->getName());
}
if (global_dtors->getNumUses() > 0)
report_fatal_error("llvm.global_dtors uses count is > 0!", false);
global_dtors->removeFromParent();
}
示例7: getGetElementPtr
Constant *ShadowStackGC::GetFrameMap(Function &F) {
// doInitialization creates the abstract type of this value.
Type *VoidPtr = Type::getInt8PtrTy(F.getContext());
// Truncate the ShadowStackDescriptor if some metadata is null.
unsigned NumMeta = 0;
SmallVector<Constant*, 16> Metadata;
for (unsigned I = 0; I != Roots.size(); ++I) {
Constant *C = cast<Constant>(Roots[I].first->getArgOperand(1));
if (!C->isNullValue())
NumMeta = I + 1;
Metadata.push_back(ConstantExpr::getBitCast(C, VoidPtr));
}
Metadata.resize(NumMeta);
Type *Int32Ty = Type::getInt32Ty(F.getContext());
Constant *BaseElts[] = {
ConstantInt::get(Int32Ty, Roots.size(), false),
ConstantInt::get(Int32Ty, NumMeta, false),
};
Constant *DescriptorElts[] = {
ConstantStruct::get(FrameMapTy, BaseElts),
ConstantArray::get(ArrayType::get(VoidPtr, NumMeta), Metadata)
};
Type *EltTys[] = { DescriptorElts[0]->getType(),DescriptorElts[1]->getType()};
StructType *STy = StructType::create(EltTys, "gc_map."+utostr(NumMeta));
Constant *FrameMap = ConstantStruct::get(STy, DescriptorElts);
// FIXME: Is this actually dangerous as WritingAnLLVMPass.html claims? Seems
// that, short of multithreaded LLVM, it should be safe; all that is
// necessary is that a simple Module::iterator loop not be invalidated.
// Appending to the GlobalVariable list is safe in that sense.
//
// All of the output passes emit globals last. The ExecutionEngine
// explicitly supports adding globals to the module after
// initialization.
//
// Still, if it isn't deemed acceptable, then this transformation needs
// to be a ModulePass (which means it cannot be in the 'llc' pipeline
// (which uses a FunctionPassManager (which segfaults (not asserts) if
// provided a ModulePass))).
Constant *GV = new GlobalVariable(*F.getParent(), FrameMap->getType(), true,
GlobalVariable::InternalLinkage,
FrameMap, "__gc_" + F.getName());
Constant *GEPIndices[2] = {
ConstantInt::get(Type::getInt32Ty(F.getContext()), 0),
ConstantInt::get(Type::getInt32Ty(F.getContext()), 0)
};
return ConstantExpr::getGetElementPtr(GV, GEPIndices);
}
示例8: addConditions
static void addConditions(CallSite CS, const ConditionsTy &Conditions) {
for (auto &Cond : Conditions) {
Value *Arg = Cond.first->getOperand(0);
Constant *ConstVal = cast<Constant>(Cond.first->getOperand(1));
if (Cond.second == ICmpInst::ICMP_EQ)
setConstantInArgument(CS, Arg, ConstVal);
else if (ConstVal->getType()->isPointerTy() && ConstVal->isNullValue()) {
assert(Cond.second == ICmpInst::ICMP_NE);
addNonNullAttribute(CS, Arg);
}
}
}
示例9: assert
// what a hack
static Function *getStubFunctionForCtorList(Module *m,
GlobalVariable *gv,
std::string name) {
assert(!gv->isDeclaration() && !gv->hasInternalLinkage() &&
"do not support old LLVM style constructor/destructor lists");
std::vector<Type *> nullary;
Function *fn = Function::Create(FunctionType::get(Type::getVoidTy(m->getContext()),
nullary, false),
GlobalVariable::InternalLinkage,
name,
m);
BasicBlock *bb = BasicBlock::Create(m->getContext(), "entry", fn);
// From lli:
// Should be an array of '{ int, void ()* }' structs. The first value is
// the init priority, which we ignore.
ConstantArray *arr = dyn_cast<ConstantArray>(gv->getInitializer());
if (arr) {
for (unsigned i=0; i<arr->getNumOperands(); i++) {
ConstantStruct *cs = cast<ConstantStruct>(arr->getOperand(i));
#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
// There is a third *optional* element in global_ctor elements (``i8
// @data``).
assert((cs->getNumOperands() == 2 || cs->getNumOperands() == 3) &&
"unexpected element in ctor initializer list");
#else
assert(cs->getNumOperands()==2 && "unexpected element in ctor initializer list");
#endif
Constant *fp = cs->getOperand(1);
if (!fp->isNullValue()) {
if (llvm::ConstantExpr *ce = dyn_cast<llvm::ConstantExpr>(fp))
fp = ce->getOperand(0);
if (Function *f = dyn_cast<Function>(fp)) {
CallInst::Create(f, "", bb);
} else {
assert(0 && "unable to get function pointer from ctor initializer list");
}
}
}
}
ReturnInst::Create(m->getContext(), bb);
return fn;
}
示例10: isSuitableForBSS
static bool isSuitableForBSS(const GlobalVariable *GV) {
Constant *C = GV->getInitializer();
// Must have zero initializer.
if (!C->isNullValue())
return false;
// Leave constant zeros in readonly constant sections, so they can be shared.
if (GV->isConstant())
return false;
// If the global has an explicit section specified, don't put it in BSS.
if (!GV->getSection().empty())
return false;
// If -nozero-initialized-in-bss is specified, don't ever use BSS.
if (NoZerosInBSS)
return false;
// Otherwise, put it in BSS!
return true;
}
示例11: RemoveFunctionReferences
static void RemoveFunctionReferences(Module *M, const char* Name) {
auto *UsedVar = M->getGlobalVariable(Name, true);
if (!UsedVar || !UsedVar->hasInitializer()) return;
if (isa<ConstantAggregateZero>(UsedVar->getInitializer())) {
assert(UsedVar->use_empty());
UsedVar->eraseFromParent();
return;
}
auto *OldUsedVal = cast<ConstantArray>(UsedVar->getInitializer());
std::vector<Constant*> Used;
for(Value *V : OldUsedVal->operand_values()) {
Constant *Op = cast<Constant>(V->stripPointerCasts());
if(!Op->isNullValue()) {
Used.push_back(cast<Constant>(V));
}
}
auto *NewValElemTy = OldUsedVal->getType()->getElementType();
auto *NewValTy = ArrayType::get(NewValElemTy, Used.size());
auto *NewUsedVal = ConstantArray::get(NewValTy, Used);
UsedVar->mutateType(NewUsedVal->getType()->getPointerTo());
UsedVar->setInitializer(NewUsedVal);
}
示例12: lowerGlobalCtors
void MemoryInstrumenter::lowerGlobalCtors(Module &M) {
// Find llvm.global_ctors.
GlobalVariable *GV = M.getNamedGlobal("llvm.global_ctors");
if (!GV)
return;
assert(!GV->isDeclaration() && !GV->hasLocalLinkage());
// Should be an array of '{ int, void ()* }' structs. The first value is
// the init priority, which must be 65535 if the bitcode is generated using
// clang.
if (ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer())) {
for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
ConstantStruct *CS =
dyn_cast<ConstantStruct>(InitList->getOperand(i));
assert(CS);
assert(CS->getNumOperands() == 2);
// Get the priority.
ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0));
assert(Priority);
// TODO: For now, we assume all priorities must be 65535.
assert(Priority->equalsInt(65535));
// Get the constructor function.
Constant *FP = CS->getOperand(1);
if (FP->isNullValue())
break; // Found a null terminator, exit.
// Explicitly call the constructor at the main entry.
CallInst::Create(FP, "", Main->begin()->getFirstNonPHI());
}
}
// Clear the global_ctors array.
// Use eraseFromParent() instead of removeFromParent().
GV->eraseFromParent();
}
示例13: ConstantFoldCompareInstOperands
static LazyValueInfo::Tristate
getPredicateResult(unsigned Pred, Constant *C, LVILatticeVal &Result,
const DataLayout *DL, TargetLibraryInfo *TLI) {
// If we know the value is a constant, evaluate the conditional.
Constant *Res = nullptr;
if (Result.isConstant()) {
Res = ConstantFoldCompareInstOperands(Pred, Result.getConstant(), C, DL,
TLI);
if (ConstantInt *ResCI = dyn_cast<ConstantInt>(Res))
return ResCI->isZero() ? LazyValueInfo::False : LazyValueInfo::True;
return LazyValueInfo::Unknown;
}
if (Result.isConstantRange()) {
ConstantInt *CI = dyn_cast<ConstantInt>(C);
if (!CI) return LazyValueInfo::Unknown;
ConstantRange CR = Result.getConstantRange();
if (Pred == ICmpInst::ICMP_EQ) {
if (!CR.contains(CI->getValue()))
return LazyValueInfo::False;
if (CR.isSingleElement() && CR.contains(CI->getValue()))
return LazyValueInfo::True;
} else if (Pred == ICmpInst::ICMP_NE) {
if (!CR.contains(CI->getValue()))
return LazyValueInfo::True;
if (CR.isSingleElement() && CR.contains(CI->getValue()))
return LazyValueInfo::False;
}
// Handle more complex predicates.
ConstantRange TrueValues =
ICmpInst::makeConstantRange((ICmpInst::Predicate)Pred, CI->getValue());
if (TrueValues.contains(CR))
return LazyValueInfo::True;
if (TrueValues.inverse().contains(CR))
return LazyValueInfo::False;
return LazyValueInfo::Unknown;
}
if (Result.isNotConstant()) {
// If this is an equality comparison, we can try to fold it knowing that
// "V != C1".
if (Pred == ICmpInst::ICMP_EQ) {
// !C1 == C -> false iff C1 == C.
Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_NE,
Result.getNotConstant(), C, DL,
TLI);
if (Res->isNullValue())
return LazyValueInfo::False;
} else if (Pred == ICmpInst::ICMP_NE) {
// !C1 != C -> true iff C1 == C.
Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_NE,
Result.getNotConstant(), C, DL,
TLI);
if (Res->isNullValue())
return LazyValueInfo::True;
}
return LazyValueInfo::Unknown;
}
return LazyValueInfo::Unknown;
}
示例14: TestFuncs
bool ReduceCrashingFunctions::TestFuncs(std::vector<Function*> &Funcs) {
// If main isn't present, claim there is no problem.
if (KeepMain && std::find(Funcs.begin(), Funcs.end(),
BD.getProgram()->getFunction("main")) ==
Funcs.end())
return false;
// Clone the program to try hacking it apart...
ValueToValueMapTy VMap;
Module *M = CloneModule(BD.getProgram(), VMap);
// Convert list to set for fast lookup...
std::set<Function*> Functions;
for (unsigned i = 0, e = Funcs.size(); i != e; ++i) {
Function *CMF = cast<Function>(VMap[Funcs[i]]);
assert(CMF && "Function not in module?!");
assert(CMF->getFunctionType() == Funcs[i]->getFunctionType() && "wrong ty");
assert(CMF->getName() == Funcs[i]->getName() && "wrong name");
Functions.insert(CMF);
}
outs() << "Checking for crash with only these functions: ";
PrintFunctionList(Funcs);
outs() << ": ";
if (!ReplaceFuncsWithNull) {
// Loop over and delete any functions which we aren't supposed to be playing
// with...
for (Function &I : *M)
if (!I.isDeclaration() && !Functions.count(&I))
DeleteFunctionBody(&I);
} else {
std::vector<GlobalValue*> ToRemove;
// First, remove aliases to functions we're about to purge.
for (GlobalAlias &Alias : M->aliases()) {
Constant *Root = Alias.getAliasee()->stripPointerCasts();
Function *F = dyn_cast<Function>(Root);
if (F) {
if (Functions.count(F))
// We're keeping this function.
continue;
} else if (Root->isNullValue()) {
// This referenced a globalalias that we've already replaced,
// so we still need to replace this alias.
} else if (!F) {
// Not a function, therefore not something we mess with.
continue;
}
PointerType *Ty = cast<PointerType>(Alias.getType());
Constant *Replacement = ConstantPointerNull::get(Ty);
Alias.replaceAllUsesWith(Replacement);
ToRemove.push_back(&Alias);
}
for (Function &I : *M) {
if (!I.isDeclaration() && !Functions.count(&I)) {
PointerType *Ty = cast<PointerType>(I.getType());
Constant *Replacement = ConstantPointerNull::get(Ty);
I.replaceAllUsesWith(Replacement);
ToRemove.push_back(&I);
}
}
for (auto *F : ToRemove) {
F->eraseFromParent();
}
// Finally, remove any null members from any global intrinsic.
RemoveFunctionReferences(M, "llvm.used");
RemoveFunctionReferences(M, "llvm.compiler.used");
}
// Try running the hacked up program...
if (TestFn(BD, M)) {
BD.setNewProgram(M); // It crashed, keep the trimmed version...
// Make sure to use function pointers that point into the now-current
// module.
Funcs.assign(Functions.begin(), Functions.end());
return true;
}
delete M;
return false;
}
示例15: calculateGraphs
//
// Method: postOrderInline()
//
// Description:
// This methods does a post order traversal of the call graph and performs
// bottom-up inlining of the DSGraphs.
//
void
BUDataStructures::postOrderInline (Module & M) {
// Variables used for Tarjan SCC-finding algorithm. These are passed into
// the recursive function used to find SCCs.
std::vector<const Function*> Stack;
std::map<const Function*, unsigned> ValMap;
unsigned NextID = 1;
// Do post order traversal on the global ctors. Use this information to update
// the globals graph.
const char *Name = "llvm.global_ctors";
GlobalVariable *GV = M.getNamedGlobal(Name);
if (GV && !(GV->isDeclaration()) && !(GV->hasLocalLinkage())) {
// Should be an array of '{ int, void ()* }' structs. The first value is
// the init priority, which we ignore.
ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
if (InitList) {
for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i)
if (ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i))) {
if (CS->getNumOperands() != 2)
break; // Not array of 2-element structs.
Constant *FP = CS->getOperand(1);
if (FP->isNullValue())
break; // Found a null terminator, exit.
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
if (CE->isCast())
FP = CE->getOperand(0);
Function *F = dyn_cast<Function>(FP);
if (F && !F->isDeclaration() && !ValMap.count(F)) {
calculateGraphs(F, Stack, NextID, ValMap);
CloneAuxIntoGlobal(getDSGraph(*F));
}
}
GlobalsGraph->removeTriviallyDeadNodes();
GlobalsGraph->maskIncompleteMarkers();
// Mark external globals incomplete.
GlobalsGraph->markIncompleteNodes(DSGraph::IgnoreGlobals);
GlobalsGraph->computeExternalFlags(DSGraph::DontMarkFormalsExternal);
GlobalsGraph->computeIntPtrFlags();
//
// Create equivalence classes for aliasing globals so that we only need to
// record one global per DSNode.
//
formGlobalECs();
// propogte information calculated
// from the globals graph to the other graphs.
for (Module::iterator F = M.begin(); F != M.end(); ++F) {
if (!(F->isDeclaration())){
DSGraph *Graph = getDSGraph(*F);
cloneGlobalsInto(Graph, DSGraph::DontCloneCallNodes |
DSGraph::DontCloneAuxCallNodes);
Graph->buildCallGraph(callgraph, GlobalFunctionList, filterCallees);
Graph->maskIncompleteMarkers();
Graph->markIncompleteNodes(DSGraph::MarkFormalArgs |
DSGraph::IgnoreGlobals);
Graph->computeExternalFlags(DSGraph::DontMarkFormalsExternal);
Graph->computeIntPtrFlags();
}
}
}
}
//
// Start the post order traversal with the main() function. If there is no
// main() function, don't worry; we'll have a separate traversal for inlining
// graphs for functions not reachable from main().
//
Function *MainFunc = M.getFunction ("main");
if (MainFunc && !MainFunc->isDeclaration()) {
calculateGraphs(MainFunc, Stack, NextID, ValMap);
CloneAuxIntoGlobal(getDSGraph(*MainFunc));
}
//
// Calculate the graphs for any functions that are unreachable from main...
//
for (Function &F : M)
if (!F.isDeclaration() && !ValMap.count(&F)) {
if (MainFunc)
DEBUG(errs() << debugname << ": Function unreachable from main: "
<< F.getName() << "\n");
calculateGraphs(&F, Stack, NextID, ValMap); // Calculate all graphs.
CloneAuxIntoGlobal(getDSGraph(F));
// Mark this graph as processed. Do this by finding all functions
// in the graph that map to it, and mark them visited.
// Note that this really should be handled neatly by calculateGraphs
// itself, not here. However this catches the worst offenders.
DSGraph *G = getDSGraph(F);
//.........这里部分代码省略.........