本文整理汇总了C++中ConstantStruct::getNumOperands方法的典型用法代码示例。如果您正苦于以下问题:C++ ConstantStruct::getNumOperands方法的具体用法?C++ ConstantStruct::getNumOperands怎么用?C++ ConstantStruct::getNumOperands使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ConstantStruct
的用法示例。
在下文中一共展示了ConstantStruct::getNumOperands方法的6个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: 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;
}
示例2: Element
CtorDtorIterator::Element CtorDtorIterator::operator*() const {
ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(I));
assert(CS && "Unrecognized type in llvm.global_ctors/llvm.global_dtors");
Constant *FuncC = CS->getOperand(1);
Function *Func = nullptr;
// Extract function pointer, pulling off any casts.
while (FuncC) {
if (Function *F = dyn_cast_or_null<Function>(FuncC)) {
Func = F;
break;
} else if (ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(FuncC)) {
if (CE->isCast())
FuncC = dyn_cast_or_null<ConstantExpr>(CE->getOperand(0));
else
break;
} else {
// This isn't anything we recognize. Bail out with Func left set to null.
break;
}
}
ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0));
Value *Data = CS->getNumOperands() == 3 ? CS->getOperand(2) : nullptr;
if (Data && !isa<GlobalValue>(Data))
Data = nullptr;
return Element(Priority->getZExtValue(), Func, Data);
}
示例3: processTypeInfo
void ClassHierarchyUtils::processTypeInfo(GlobalVariable* TI) {
if (find(classes.begin(), classes.end(), TI) == classes.end()) {
classes.push_back(TI);
// extract direct base classes from type_info
if (TI->hasInitializer()) {
ConstantStruct* TIinit = cast<ConstantStruct>(TI->getInitializer());
int TInumOperands = TIinit->getNumOperands();
if (TInumOperands > 2) {
// we have >= 1 base class(es).
if (TInumOperands == 3) {
// abi::__si_class_type_info
GlobalVariable* baseTI = cast<GlobalVariable>(TIinit->getOperand(2)->stripPointerCasts());
classToSubclasses[baseTI].push_back(TI);
//dbgs() << " " << *baseTI << "\n";
classToBaseOffset[TI][baseTI] = 0;
processTypeInfo(baseTI);
}
else {
// abi::__vmi_class_type_info
// (skip over first two additional fields, which are "flags" and "base_count")
for (int i=4; i<TInumOperands; i+=2) {
GlobalVariable* baseTI = cast<GlobalVariable>(TIinit->getOperand(i)->stripPointerCasts());
classToSubclasses[baseTI].push_back(TI);
int offset_flags = cast<ConstantInt>(TIinit->getOperand(i+1))->getSExtValue();
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << TI->getName() << " -> " << baseTI->getName() << "\n");
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << " offset_flags = " << offset_flags << "\n");
int offset = offset_flags >> 8; // TODO: is this value defined as a constant somewhere?
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << " offset = " << offset << "\n");
classToBaseOffset[TI][baseTI] = offset;
//dbgs() << " " << *baseTI << "\n";
processTypeInfo(baseTI);
}
}
}
}
示例4: 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();
}
示例5: processTypeInfo
void ClassHierarchyUtils::processTypeInfo(GlobalVariable* TI, Module& M) {
if (find(classes.begin(), classes.end(), TI) == classes.end()) {
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "Adding class " << TI->getName() << "\n");
classes.push_back(TI);
// First process the correspoding virtual table. We store the indexes of the primary
// and secondary vtables, indexed by the corresponding subobject offset. This will allow
// us to quickly jump to a particular sub-vtable.
if (typeInfoToVTable.find(TI) != typeInfoToVTable.end()) {
GlobalVariable* VT = typeInfoToVTable[TI];
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "Found vtable: " << VT->getName() << "\n");
ConstantStruct* VTinit = cast<ConstantStruct>(VT->getInitializer());
for (int i=0; i<VTinit->getNumOperands(); i++) {
ConstantArray* VTinitElem = cast<ConstantArray>(VTinit->getOperand(i));
for (int j=0; j<VTinitElem->getNumOperands(); j++) {
// Each sub-vtable is preceded by a reference to the class's type_info instance.
// (See https://mentorembedded.github.io/cxx-abi/abi.html).
if (TI == VTinitElem->getOperand(j)->stripPointerCasts()) {
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "Found TI at index " << i << "\n");
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "Storing mapping " << VT->getName() << " <-> " << TI->getName() << "\n");
// the offset to top is the offset from the vptr pointing to this
// sub-vtable, back to the top of the object. This will be negative,
// but the absolute value gives us the offset from the start of the
// object (i.e. first vptr), to the subobject.
int offsetToTop = 0;
if (ConstantExpr* offsetValCast = dyn_cast<ConstantExpr>(VTinitElem->getOperand(j-1)->stripPointerCasts())) {
ConstantInt* offsetVal = cast<ConstantInt>(offsetValCast->getOperand(0));
offsetToTop = offsetVal->getSExtValue(); // will be 0 for the primary
}
if (offsetToTop > 0) {
report_fatal_error("ERROR: offsetToTop is positive!");
}
else {
offsetToTop *= -1;
}
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "offsetToTop: " << offsetToTop << "\n")
vTableToSecondaryVTableMaps[VT][offsetToTop] = pair<int, int>(i, j+1);
}
}
}
}
else {
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "No vtable found for " << TI->getName() << "\n");
}
// Now process the type_info struct, extract direct base class info (what
// their subobject offsets are, or if they are virtual then their
// virtual-base-offset-offset)
if (TI->hasInitializer()) {
ConstantStruct* TIinit = cast<ConstantStruct>(TI->getInitializer());
int TInumOperands = TIinit->getNumOperands();
if (TInumOperands > 2) { // first two operands are vptr and type name
// we have >= 1 base class(es).
if (TInumOperands == 3) {
// abi::__si_class_type_info: single, public, non-virtual base at
// offset 0
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "abi::__si_class_type_info\n");
GlobalVariable* baseTI = cast<GlobalVariable>(TIinit->getOperand(2)->stripPointerCasts());
classToSubclasses[baseTI].push_back(TI);
//dbgs() << " " << *baseTI << "\n";
classToBaseOffset[TI][baseTI] = 0;
processTypeInfo(baseTI, M);
}
else {
// abi::__vmi_class_type_info: all other cases
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "abi::__vmi_class_type_info\n");
// (skip over first two additional fields, which are "flags" and "base_count")
for (int i=4; i<TInumOperands; i+=2) {
GlobalVariable* baseTI = cast<GlobalVariable>(TIinit->getOperand(i)->stripPointerCasts());
classToSubclasses[baseTI].push_back(TI);
long offset_flags = cast<ConstantInt>(TIinit->getOperand(i+1))->getSExtValue();
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << TI->getName() << " -> " << baseTI->getName() << "\n");
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << " offset_flags = " << offset_flags << "\n");
ptrdiff_t offset = offset_flags >> offset_shift;
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << " offset = " << offset << "\n");
// If this a virtual base class, then we obtain the
// vbase-offset-offset. This is the offset from the start of the
// derived class's (primary) vtable to the location containing the
// vbase-offset, which is the offset from the start of the object
// to the virtual base's subobject. Note that virtual base
// subobjects only exist once and are laid out after all other
// non-virtual objects. We keep track of the vbase-offset-offset,
// so that we can find the vbase offset when going down the class
// hierarchy. (The vbase offset may differ every time but the
// vbase-offset-offset will remain the same relative to the current
// class's vtable in subclasses).
if (offset_flags & virtual_mask) { // is this a virtual base class?
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "virtual base class: " << baseTI->getName() << "\n");
int vbaseOffsetOffset = offset/sizeof(long); // this should be negative
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "vbase-offset-offset: " << vbaseOffsetOffset << "\n");
classToVBaseOffsetOffset[TI][baseTI] = vbaseOffsetOffset;
if (typeInfoToVTable.find(TI) != typeInfoToVTable.end()) {
GlobalVariable* VT = typeInfoToVTable[TI];
int vbaseOffsetIdx = vTableToSecondaryVTableMaps[VT][0].second+vbaseOffsetOffset;
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "vbase-offset-idx: " << vbaseOffsetIdx << "\n");
}
else {
//.........这里部分代码省略.........
示例6: analyzeDestructor
/// analyzeDestructor - Given the heap.metadata argument to swift_allocObject,
/// take a look a the destructor and try to decide if it has side effects or any
/// other bad effects that can prevent it from being optimized.
static DtorKind analyzeDestructor(Value *P) {
// If we have a null pointer for the metadata info, the dtor has no side
// effects. Actually, the final release would crash. This is really only
// useful for writing testcases.
if (isa<ConstantPointerNull>(P->stripPointerCasts()))
return DtorKind::NoSideEffects;
// We have to have a known heap metadata value, reject dynamically computed
// ones, or places
GlobalVariable *GV = dyn_cast<GlobalVariable>(P->stripPointerCasts());
if (GV == 0 || GV->mayBeOverridden()) return DtorKind::Unknown;
ConstantStruct *CS = dyn_cast_or_null<ConstantStruct>(GV->getInitializer());
if (CS == 0 || CS->getNumOperands() == 0) return DtorKind::Unknown;
// FIXME: Would like to abstract the dtor slot (#0) out from this to somewhere
// unified.
enum { DTorSlotOfHeapMetadata = 0 };
Function *DtorFn =dyn_cast<Function>(CS->getOperand(DTorSlotOfHeapMetadata));
if (DtorFn == 0 || DtorFn->mayBeOverridden() || DtorFn->hasExternalLinkage())
return DtorKind::Unknown;
// Okay, we have a body, and we can trust it. If the function is marked
// readonly, then we know it can't have any interesting side effects, so we
// don't need to analyze it at all.
if (DtorFn->onlyReadsMemory())
return DtorKind::NoSideEffects;
// The first argument is the object being destroyed.
assert(DtorFn->arg_size() == 1 && !DtorFn->isVarArg() &&
"expected a single object argument to destructors");
Value *ThisObject = &*DtorFn->arg_begin();
// Scan the body of the function, looking for anything scary.
for (BasicBlock &BB : *DtorFn) {
for (Instruction &I : BB) {
// Note that the destructor may not be in any particular canonical form.
switch (classifyInstruction(I)) {
// These instructions should not reach here based on the pass ordering.
// i.e. LLVMARCOpt -> LLVMContractOpt.
case RT_RetainN:
case RT_UnknownRetainN:
case RT_BridgeRetainN:
case RT_ReleaseN:
case RT_UnknownReleaseN:
case RT_BridgeReleaseN:
llvm_unreachable("These are only created by LLVMARCContract !");
case RT_NoMemoryAccessed:
case RT_AllocObject:
case RT_FixLifetime:
case RT_CheckUnowned:
// Skip over random instructions that don't touch memory in the caller.
continue;
case RT_RetainUnowned:
case RT_BridgeRetain: // x = swift_bridgeRetain(y)
case RT_Retain: { // swift_retain(obj)
// Ignore retains of the "self" object, no resurrection is possible.
Value *ThisRetainedObject = cast<CallInst>(I).getArgOperand(0);
if (ThisRetainedObject->stripPointerCasts() ==
ThisObject->stripPointerCasts())
continue;
// Otherwise, we may be retaining something scary.
break;
}
case RT_Release: {
// If we get to a release that is provably to this object, then we can
// ignore it.
Value *ThisReleasedObject = cast<CallInst>(I).getArgOperand(0);
if (ThisReleasedObject->stripPointerCasts() ==
ThisObject->stripPointerCasts())
continue;
// Otherwise, we may be retaining something scary.
break;
}
case RT_ObjCRelease:
case RT_ObjCRetain:
case RT_UnknownRetain:
case RT_UnknownRelease:
case RT_BridgeRelease:
// Objective-C retain and release can have arbitrary side effects.
break;
case RT_Unknown:
// Ignore all instructions with no side effects.
if (!I.mayHaveSideEffects()) continue;
// store, memcpy, memmove *to* the object can be dropped.
if (StoreInst *SI = dyn_cast<StoreInst>(&I)) {
if (SI->getPointerOperand()->stripInBoundsOffsets() == ThisObject)
continue;
}
//.........这里部分代码省略.........