本文整理汇总了C++中ConstantArray::getNumOperands方法的典型用法代码示例。如果您正苦于以下问题:C++ ConstantArray::getNumOperands方法的具体用法?C++ ConstantArray::getNumOperands怎么用?C++ ConstantArray::getNumOperands使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ConstantArray
的用法示例。
在下文中一共展示了ConstantArray::getNumOperands方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: emitUses
void InstrProfiling::emitUses() {
if (UsedVars.empty())
return;
GlobalVariable *LLVMUsed = M->getGlobalVariable("llvm.used");
std::vector<Constant *> MergedVars;
if (LLVMUsed) {
// Collect the existing members of llvm.used.
ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
for (unsigned I = 0, E = Inits->getNumOperands(); I != E; ++I)
MergedVars.push_back(Inits->getOperand(I));
LLVMUsed->eraseFromParent();
}
Type *i8PTy = Type::getInt8PtrTy(M->getContext());
// Add uses for our data.
for (auto *Value : UsedVars)
MergedVars.push_back(
ConstantExpr::getBitCast(cast<Constant>(Value), i8PTy));
// Recreate llvm.used.
ArrayType *ATy = ArrayType::get(i8PTy, MergedVars.size());
LLVMUsed =
new GlobalVariable(*M, ATy, false, GlobalValue::AppendingLinkage,
ConstantArray::get(ATy, MergedVars), "llvm.used");
LLVMUsed->setSection("llvm.metadata");
}
示例2: removeGlobalCtors
/// Given a specified llvm.global_ctors list, remove the listed elements.
static void removeGlobalCtors(GlobalVariable *GCL, const BitVector &CtorsToRemove) {
// Filter out the initializer elements to remove.
ConstantArray *OldCA = cast<ConstantArray>(GCL->getInitializer());
SmallVector<Constant *, 10> CAList;
for (unsigned I = 0, E = OldCA->getNumOperands(); I < E; ++I)
if (!CtorsToRemove.test(I))
CAList.push_back(OldCA->getOperand(I));
// Create the new array initializer.
ArrayType *ATy =
ArrayType::get(OldCA->getType()->getElementType(), CAList.size());
Constant *CA = ConstantArray::get(ATy, CAList);
// If we didn't change the number of elements, don't create a new GV.
if (CA->getType() == OldCA->getType()) {
GCL->setInitializer(CA);
return;
}
// Create the new global and insert it next to the existing list.
GlobalVariable *NGV =
new GlobalVariable(CA->getType(), GCL->isConstant(), GCL->getLinkage(),
CA, "", GCL->getThreadLocalMode());
GCL->getParent()->getGlobalList().insert(GCL->getIterator(), NGV);
NGV->takeName(GCL);
// Nuke the old list, replacing any uses with the new one.
if (!GCL->use_empty()) {
Constant *V = NGV;
if (V->getType() != GCL->getType())
V = ConstantExpr::getBitCast(V, GCL->getType());
GCL->replaceAllUsesWith(V);
}
GCL->eraseFromParent();
}
示例3: 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>());
}
}
}
示例4: findClassHierarchy
void ClassHierarchyUtils::findClassHierarchy(Module& M) {
// Extract class hierarchy using std::type_info structures rather than debug
// info. The former works even for when there are anonymous namespaces.
// (for more info, see http://mentorembedded.github.io/cxx-abi/abi.html)
//
// Class names are usually global, except in the case of anonymous namespaces, in which case
// they may be renamed during linking. This renaming is not consistent across type_info and
// vtables. For example, the following are for the same class:
// _ZTIN7content12_GLOBAL__N_115HeaderFlattenerE60908 and
// _ZTVN7content12_GLOBAL__N_115HeaderFlattenerE60906.
//
// (renamed from
// _ZTVN7content12_GLOBAL__N_115HeaderFlattenerE and
// _ZTIN7content12_GLOBAL__N_115HeaderFlattenerE).
//
// VTables give us the corresponding type_info, so we process them first and store
// the VT <-> TI mappings, as this will be useful later.
for (Module::global_iterator I=M.global_begin(), E=M.global_end(); I != E; I++) {
GlobalVariable* VT = &*I;
if (VT->getName().startswith("_ZTV")) {
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "Found vtable: " << VT->getName() << "\n");
if (VT->hasInitializer()) {
ConstantStruct* VTinit = cast<ConstantStruct>(VT->getInitializer());
// all occurrences of a type_info object refer to this class's type_info, so we
// can pick the first array
ConstantArray* VTinitElem = cast<ConstantArray>(VTinit->getOperand(0));
for (int i=0; i<VTinitElem->getNumOperands(); i++) {
// type_info will be the first global variable in the array.
// It's not always at a fixed index so we have to search for it...
// The first one corresponds to the primary vtable, all others
// correspond to secondary vtables. All type_info occurrences will
// be the same.
if (GlobalVariable* TI = dyn_cast<GlobalVariable>(VTinitElem->getOperand(i)->stripPointerCasts())) {
if (typeInfoToVTable.find(TI) != typeInfoToVTable.end()) {
report_fatal_error(TI->getName() + " <-> " + VT->getName() + " mapping already exists!");
}
// Record TI <-> VT mappings, as they will be useful later
typeInfoToVTable[TI] = VT;
vTableToTypeInfo[VT] = TI;
break; // we only need to process the first one
}
}
}
else {
SDEBUG("soaap.util.classhierarchy", 1, dbgs() << "WARNING: VTable " << VT->getName() << " does not have initializer\n");
}
}
}
// Process type_info structures, recording class-hierarchy information and base offsets
for (Module::global_iterator I=M.global_begin(), E=M.global_end(); I != E; I++) {
GlobalVariable* G = &*I;
if (G->getName().startswith("_ZTI")) {
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "Found type_info: " << G->getName() << "\n");
processTypeInfo(G, M);
}
}
SDEBUG("soaap.util.classhierarchy", 3, ppClassHierarchy(classToSubclasses));
}
示例5: readFuncList
static void readFuncList(GlobalVariable *Array, std::vector<Constant*> *Funcs) {
if (!Array->hasInitializer())
return;
Constant *Init = Array->getInitializer();
ArrayType *Ty = dyn_cast<ArrayType>(Init->getType());
if (!Ty) {
errs() << "Initializer: " << *Array->getInitializer() << "\n";
report_fatal_error("ExpandCtors: Initializer is not of array type");
}
if (Ty->getNumElements() == 0)
return;
ConstantArray *InitList = dyn_cast<ConstantArray>(Init);
if (!InitList) {
errs() << "Initializer: " << *Array->getInitializer() << "\n";
report_fatal_error("ExpandCtors: Unexpected initializer ConstantExpr");
}
std::vector<FuncArrayEntry> FuncsToSort;
for (unsigned Index = 0; Index < InitList->getNumOperands(); ++Index) {
ConstantStruct *CS = cast<ConstantStruct>(InitList->getOperand(Index));
FuncArrayEntry Entry;
Entry.priority = cast<ConstantInt>(CS->getOperand(0))->getZExtValue();
Entry.func = CS->getOperand(1);
FuncsToSort.push_back(Entry);
}
std::sort(FuncsToSort.begin(), FuncsToSort.end(), compareEntries);
for (std::vector<FuncArrayEntry>::iterator Iter = FuncsToSort.begin();
Iter != FuncsToSort.end();
++Iter) {
Funcs->push_back(Iter->func);
}
}
示例6: lowerCoverageData
void InstrProfiling::lowerCoverageData(GlobalVariable *CoverageData) {
CoverageData->setSection(getCoverageSection());
CoverageData->setAlignment(8);
Constant *Init = CoverageData->getInitializer();
// We're expecting { i32, i32, i32, i32, [n x { i8*, i32, i32 }], [m x i8] }
// for some C. If not, the frontend's given us something broken.
assert(Init->getNumOperands() == 6 && "bad number of fields in coverage map");
assert(isa<ConstantArray>(Init->getAggregateElement(4)) &&
"invalid function list in coverage map");
ConstantArray *Records = cast<ConstantArray>(Init->getAggregateElement(4));
for (unsigned I = 0, E = Records->getNumOperands(); I < E; ++I) {
Constant *Record = Records->getOperand(I);
Value *V = const_cast<Value *>(Record->getOperand(0))->stripPointerCasts();
assert(isa<GlobalVariable>(V) && "Missing reference to function name");
GlobalVariable *Name = cast<GlobalVariable>(V);
// If we have region counters for this name, we've already handled it.
auto It = RegionCounters.find(Name);
if (It != RegionCounters.end())
continue;
// Move the name variable to the right section.
Name->setSection(getNameSection());
Name->setAlignment(1);
}
}
示例7: findClassHierarchy
void ClassHierarchyUtils::findClassHierarchy(Module& M) {
// extract call hierarchy using std::type_info structures rather
// than debug info. The former works even for when there are anonymous
// namespaces. type_info structs can be obtained from vtable globals.
// (for more info, see http://mentorembedded.github.io/cxx-abi/abi.html)
for (Module::global_iterator I=M.global_begin(), E=M.global_end(); I != E; I++) {
GlobalVariable* G = &*I;
if (G->getName().startswith("_ZTV")) {
if (G->hasInitializer()) {
SDEBUG("soaap.util.classhierarchy", 3, G->dump());
ConstantArray* Ginit = cast<ConstantArray>(G->getInitializer());
// Ginit[1] is the type_info global for this vtable's type
bool typeInfoFound = false;
bool primaryVTable = true;
for (int i=0; i<Ginit->getNumOperands(); i++) {
// typeinfo will be the first global variable in the array.
// It's not always at a fixed index so we have to search for it...
if (GlobalVariable* TI = dyn_cast<GlobalVariable>(Ginit->getOperand(i)->stripPointerCasts())) {
//TI->dump();
typeInfoToVTable[TI] = G;
vTableToTypeInfo[G] = TI;
processTypeInfo(TI); // process TI recursively (it contains refs to super-class TIs)
typeInfoFound = true;
if (primaryVTable) {
primaryVTable = false;
vTableToSecondaryVTableMaps[G][0] = i+1; // i+1 is also the size of the vtable header
}
else {
// offset_to_top is at the previous index
ConstantExpr* offsetValCast = cast<ConstantExpr>(Ginit->getOperand(i-1)->stripPointerCasts());
ConstantInt* offsetVal = cast<ConstantInt>(offsetValCast->getOperand(0));
int offsetToTop = offsetVal->getSExtValue();
if (offsetToTop > 0) {
dbgs() << "ERROR: offsetToTop is positive!\n";
G->dump();
}
else {
offsetToTop *= -1;
}
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "offsetToTop: " << offsetToTop << "\n");
vTableToSecondaryVTableMaps[G][offsetToTop] = i+1;
}
}
}
if (!typeInfoFound) {
dbgs() << "ERROR: vtable initializer is not a global variable...\n";
dbgs() << *G << " = " << *Ginit << "\n";
}
}
}
}
SDEBUG("soaap.util.classhierarchy", 3, ppClassHierarchy(classToSubclasses));
}
示例8: if
bool SDFix::fixDestructors2() {
bool replaced = false;
for (GlobalVariable& gv : module->getGlobalList()) {
if (! sd_isVtableName_ref(gv.getName()))
continue;
else if (! gv.hasInitializer())
continue;
Constant* init = gv.getInitializer();
assert(init);
ConstantArray* vtable = dyn_cast<ConstantArray>(init);
assert(vtable);
for(unsigned i=0; i<vtable->getNumOperands(); i++) {
Constant* destructor = sd_getDestructorFunction(vtable->getOperand(i));
if (destructor == NULL)
continue;
// get the type from its name
unsigned s = destructor->getName().size();
char type = destructor->getName()[s-3];
assert('0' <= type && type <= '2');
unsigned typeInt = type - '0';
DestructorInfo di(destructor, i);
if(di.isDefined)
continue;
// this only handles the 1 -> 2 conversion
assert(typeInt == 1);
Function* f1 = di.getFunction();
assert(f1);
std::string gv2Name = f1->getName();
unsigned l = gv2Name.length();
gv2Name = gv2Name.replace(l-3, 1, "2");
Function* f2 = module->getFunction(gv2Name);
assert(f2 && ! f2->isDeclaration());
sd_print("Replacing %s with %s inside %s\n",
f1->getName().data(),
gv2Name.c_str(),
gv.getName().data());
f1->replaceAllUsesWith(f2);
replaced = true;
}
}
return replaced;
}
示例9: SplitStaticCtorDtor
/// SplitStaticCtorDtor - A module was recently split into two parts, M1/M2, and
/// M1 has all of the global variables. If M2 contains any functions that are
/// static ctors/dtors, we need to add an llvm.global_[cd]tors global to M2, and
/// prune appropriate entries out of M1s list.
static void SplitStaticCtorDtor(const char *GlobalName, Module *M1, Module *M2,
DenseMap<const Value*, Value*> ValueMap) {
GlobalVariable *GV = M1->getNamedGlobal(GlobalName);
if (!GV || GV->isDeclaration() || GV->hasLocalLinkage() ||
!GV->use_empty()) return;
std::vector<std::pair<Function*, int> > M1Tors, M2Tors;
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.
if (CS->getOperand(1)->isNullValue())
break; // Found a null terminator, stop here.
ConstantInt *CI = dyn_cast<ConstantInt>(CS->getOperand(0));
int Priority = CI ? CI->getSExtValue() : 0;
Constant *FP = CS->getOperand(1);
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
if (CE->isCast())
FP = CE->getOperand(0);
if (Function *F = dyn_cast<Function>(FP)) {
if (!F->isDeclaration())
M1Tors.push_back(std::make_pair(F, Priority));
else {
// Map to M2's version of the function.
F = cast<Function>(ValueMap[F]);
M2Tors.push_back(std::make_pair(F, Priority));
}
}
}
}
GV->eraseFromParent();
if (!M1Tors.empty()) {
Constant *M1Init = GetTorInit(M1Tors);
new GlobalVariable(*M1, M1Init->getType(), false,
GlobalValue::AppendingLinkage,
M1Init, GlobalName);
}
GV = M2->getNamedGlobal(GlobalName);
assert(GV && "Not a clone of M1?");
assert(GV->use_empty() && "llvm.ctors shouldn't have uses!");
GV->eraseFromParent();
if (!M2Tors.empty()) {
Constant *M2Init = GetTorInit(M2Tors);
new GlobalVariable(*M2, M2Init->getType(), false,
GlobalValue::AppendingLinkage,
M2Init, GlobalName);
}
}
示例10: findUsedValues
static void findUsedValues(GlobalVariable *LLVMUsed,
SmallPtrSetImpl<GlobalValue*> &UsedValues) {
if (!LLVMUsed) return;
ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i)
if (GlobalValue *GV =
dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts()))
UsedValues.insert(GV);
}
示例11: FindUsedValues
/// Find values that are marked as llvm.used.
static void FindUsedValues(GlobalVariable *LLVMUsed,
SmallPtrSet<const GlobalValue*, 8> &UsedValues) {
if (LLVMUsed == 0) return;
ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i) {
Value *Operand = Inits->getOperand(i)->stripPointerCastsNoFollowAliases();
GlobalValue *GV = cast<GlobalValue>(Operand);
UsedValues.insert(GV);
}
}
示例12: parseGlobalCtors
/// Given a llvm.global_ctors list that we can understand,
/// return a list of the functions and null terminator as a vector.
static std::vector<Function *> parseGlobalCtors(GlobalVariable *GV) {
if (GV->getInitializer()->isNullValue())
return std::vector<Function *>();
ConstantArray *CA = cast<ConstantArray>(GV->getInitializer());
std::vector<Function *> Result;
Result.reserve(CA->getNumOperands());
for (auto &V : CA->operands()) {
ConstantStruct *CS = cast<ConstantStruct>(V);
Result.push_back(dyn_cast<Function>(CS->getOperand(1)));
}
return Result;
}
示例13: parseGlobalCtors
static std::vector<Function*> parseGlobalCtors(GlobalVariable *GV) {
if (GV->getInitializer()->isNullValue())
return std::vector<Function *>();
ConstantArray *CA = cast<ConstantArray>(GV->getInitializer());
std::vector<Function *> Result;
Result.reserve(CA->getNumOperands());
for (User::op_iterator i = CA->op_begin(), e = CA->op_end(); i != e; ++i) {
ConstantStruct *CS = cast<ConstantStruct>(*i);
Result.push_back(dyn_cast<Function>(CS->getOperand(1)));
}
return Result;
}
示例14: EmitLLVMUsedList
/// EmitLLVMUsedList - For targets that define a TAI::UsedDirective, mark each
/// global in the specified llvm.used list as being used with this directive.
void AsmPrinter::EmitLLVMUsedList(Constant *List) {
const char *Directive = TAI->getUsedDirective();
// Should be an array of 'sbyte*'.
ConstantArray *InitList = dyn_cast<ConstantArray>(List);
if (InitList == 0) return;
for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
O << Directive;
EmitConstantValueOnly(InitList->getOperand(i));
O << "\n";
}
}
示例15: lowerCoverageData
void InstrProfiling::lowerCoverageData(GlobalVariable *CoverageNamesVar) {
ConstantArray *Names =
cast<ConstantArray>(CoverageNamesVar->getInitializer());
for (unsigned I = 0, E = Names->getNumOperands(); I < E; ++I) {
Constant *NC = Names->getOperand(I);
Value *V = NC->stripPointerCasts();
assert(isa<GlobalVariable>(V) && "Missing reference to function name");
GlobalVariable *Name = cast<GlobalVariable>(V);
Name->setLinkage(GlobalValue::PrivateLinkage);
ReferencedNames.push_back(Name);
}
}