本文整理汇总了C++中ConstantArray::getOperand方法的典型用法代码示例。如果您正苦于以下问题:C++ ConstantArray::getOperand方法的具体用法?C++ ConstantArray::getOperand怎么用?C++ ConstantArray::getOperand使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ConstantArray
的用法示例。
在下文中一共展示了ConstantArray::getOperand方法的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: AnalyzeModule
/// AnalyzeModule - Scan the module for global debug information.
///
void MachineModuleInfo::AnalyzeModule(Module &M) {
// Insert functions in the llvm.used array (but not llvm.compiler.used) into
// UsedFunctions.
GlobalVariable *GV = M.getGlobalVariable("llvm.used");
if (!GV || !GV->hasInitializer()) return;
// Should be an array of 'i8*'.
ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
if (InitList == 0) return;
for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i)
if (Function *F =
dyn_cast<Function>(InitList->getOperand(i)->stripPointerCasts()))
UsedFunctions.insert(F);
}
示例2: EmitXXStructorList
/// EmitXXStructorList - Emit the ctor or dtor list. This just prints out the
/// function pointers, ignoring the init priority.
void AsmPrinter::EmitXXStructorList(Constant *List) {
// Should be an array of '{ int, void ()* }' structs. The first value is the
// init priority, which we ignore.
if (!isa<ConstantArray>(List)) return;
ConstantArray *InitList = cast<ConstantArray>(List);
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())
return; // Found a null terminator, exit printing.
// Emit the function pointer.
EmitGlobalConstant(CS->getOperand(1));
}
}
示例3: 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;
}
示例4: VisitGlobalInit
/// VisitGlobalInit - The specified lattice value corresponds to a field (or
/// several) in the specified global. Merge all of the overlapping initializer
/// values into LV (up-to and until it becomes overdefined).
///
static bool VisitGlobalInit(LatticeValue *LV, Constant *Init,
unsigned FieldOffset) {
const TargetData &TD = LV->getParentGraph().getTargetData();
if (Init->isNullValue())
return LV->visitGlobalInit(Constant::getNullValue(LV->getFieldType()));
if (isa<UndefValue>(Init))
return LV->visitGlobalInit(UndefValue::get(LV->getFieldType()));
if (LV->getNode()->isArray() &&
TD.getTypeSize(Init->getType()) > LV->getNode()->getSize()) {
ConstantArray *CA = cast<ConstantArray>(Init);
for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
if (VisitGlobalInit(LV, CA->getOperand(i), FieldOffset))
return true;
return false;
}
NextStep: // Manual tail recursion
if (Init->isNullValue())
return LV->visitGlobalInit(Constant::getNullValue(LV->getFieldType()));
if (isa<UndefValue>(Init))
return LV->visitGlobalInit(UndefValue::get(LV->getFieldType()));
if (Init->getType()->isFirstClassType()) {
assert(FieldOffset == 0 && "GV Init mismatch!");
return LV->visitGlobalInit(Init);
}
if (const StructType *STy = dyn_cast<StructType>(Init->getType())) {
const StructLayout *SL = TD.getStructLayout(STy);
unsigned Field = SL->getElementContainingOffset(FieldOffset);
FieldOffset -= SL->MemberOffsets[Field];
Init = cast<ConstantStruct>(Init)->getOperand(Field);
goto NextStep;
} else if (const ArrayType *ATy = dyn_cast<ArrayType>(Init->getType())) {
unsigned ElSz = TD.getTypeSize(ATy->getElementType());
unsigned Idx = FieldOffset / ElSz;
FieldOffset -= Idx*ElSz;
Init = cast<ConstantArray>(Init)->getOperand(Idx);
goto NextStep;
} else {
assert(0 && "Unexpected initializer type!");
return true;
}
}
示例5: doFinalization
bool CheckInserter::doFinalization(Module &M) {
// We couldn't directly add an element to a constant array, because doing so
// changes the type of the constant array.
// element type of llvm.global_ctors
StructType *ST = StructType::get(IntType,
PointerType::getUnqual(InitFiniType),
NULL); // end with null
// Move all existing elements of <GlobalName> to <Constants>.
vector<Constant *> Constants;
if (GlobalVariable *GlobalCtors = M.getNamedGlobal("llvm.global_ctors")) {
ConstantArray *CA = cast<ConstantArray>(GlobalCtors->getInitializer());
for (unsigned j = 0; j < CA->getNumOperands(); ++j) {
ConstantStruct *CS = cast<ConstantStruct>(CA->getOperand(j));
assert(CS->getType() == ST);
// Assume nobody is using the highest priority, so that <F> will be the
// first to run as a ctor.
assert(!cast<ConstantInt>(CS->getOperand(0))->isMinValue(true));
Constants.push_back(CS);
}
GlobalCtors->eraseFromParent();
}
// Add <F> with the highest priority.
Constants.push_back(ConstantStruct::get(ST,
ConstantInt::get(IntType, INT_MIN),
EnterProcess,
NULL));
// Create the new llvm.global_ctors.
ArrayType *ArrType = ArrayType::get(ST, Constants.size());
new GlobalVariable(M,
ArrType,
true,
GlobalValue::AppendingLinkage,
ConstantArray::get(ArrType, Constants),
"llvm.global_ctors");
return true;
}
示例6: GetConstantStringInfo
/// GetConstantStringInfo - This function computes the length of a
/// null-terminated C string pointed to by V. If successful, it returns true
/// and returns the string in Str. If unsuccessful, it returns false.
bool llvm::GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset,
bool StopAtNul) {
// If V is NULL then return false;
if (V == NULL) return false;
// Look through bitcast instructions.
if (BitCastInst *BCI = dyn_cast<BitCastInst>(V))
return GetConstantStringInfo(BCI->getOperand(0), Str, Offset, StopAtNul);
// If the value is not a GEP instruction nor a constant expression with a
// GEP instruction, then return false because ConstantArray can't occur
// any other way
User *GEP = 0;
if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(V)) {
GEP = GEPI;
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
if (CE->getOpcode() == Instruction::BitCast)
return GetConstantStringInfo(CE->getOperand(0), Str, Offset, StopAtNul);
if (CE->getOpcode() != Instruction::GetElementPtr)
return false;
GEP = CE;
}
if (GEP) {
// Make sure the GEP has exactly three arguments.
if (GEP->getNumOperands() != 3)
return false;
// Make sure the index-ee is a pointer to array of i8.
const PointerType *PT = cast<PointerType>(GEP->getOperand(0)->getType());
const ArrayType *AT = dyn_cast<ArrayType>(PT->getElementType());
if (AT == 0 || AT->getElementType() != Type::Int8Ty)
return false;
// Check to make sure that the first operand of the GEP is an integer and
// has value 0 so that we are sure we're indexing into the initializer.
ConstantInt *FirstIdx = dyn_cast<ConstantInt>(GEP->getOperand(1));
if (FirstIdx == 0 || !FirstIdx->isZero())
return false;
// If the second index isn't a ConstantInt, then this is a variable index
// into the array. If this occurs, we can't say anything meaningful about
// the string.
uint64_t StartIdx = 0;
if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(2)))
StartIdx = CI->getZExtValue();
else
return false;
return GetConstantStringInfo(GEP->getOperand(0), Str, StartIdx+Offset,
StopAtNul);
}
// The GEP instruction, constant or instruction, must reference a global
// variable that is a constant and is initialized. The referenced constant
// initializer is the array that we'll use for optimization.
GlobalVariable* GV = dyn_cast<GlobalVariable>(V);
if (!GV || !GV->isConstant() || !GV->hasInitializer())
return false;
Constant *GlobalInit = GV->getInitializer();
// Handle the ConstantAggregateZero case
if (isa<ConstantAggregateZero>(GlobalInit)) {
// This is a degenerate case. The initializer is constant zero so the
// length of the string must be zero.
Str.clear();
return true;
}
// Must be a Constant Array
ConstantArray *Array = dyn_cast<ConstantArray>(GlobalInit);
if (Array == 0 || Array->getType()->getElementType() != Type::Int8Ty)
return false;
// Get the number of elements in the array
uint64_t NumElts = Array->getType()->getNumElements();
if (Offset > NumElts)
return false;
// Traverse the constant array from 'Offset' which is the place the GEP refers
// to in the array.
Str.reserve(NumElts-Offset);
for (unsigned i = Offset; i != NumElts; ++i) {
Constant *Elt = Array->getOperand(i);
ConstantInt *CI = dyn_cast<ConstantInt>(Elt);
if (!CI) // This array isn't suitable, non-int initializer.
return false;
if (StopAtNul && CI->isZero())
return true; // we found end of string, success!
Str += (char)CI->getZExtValue();
}
// The array isn't null terminated, but maybe this is a memcpy, not a strcpy.
return true;
}
示例7: 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 {
//.........这里部分代码省略.........
示例8: fixDestructors
bool SDFix::fixDestructors() {
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);
// get an idea about the virtual function regions
std::vector<vtbl_pair_t> vtblRegions = findSubVtables(vtable);
// for each subvtable
for(unsigned vtblInd = 0; vtblInd < vtblRegions.size(); vtblInd++) {
// record the destructors used in the vtable
std::vector<DestructorInfo> destructors(3);
vtbl_pair_t p = vtblRegions[vtblInd];
for(unsigned i=p.first; i<p.second; 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';
// store it temporarily
destructors[typeInt] = DestructorInfo(destructor, i);
}
// deleting destructor should always be defined
assert(! destructors[0].needsReplacement());
DestructorInfo* d1 = &destructors[1];
DestructorInfo* d2 = &destructors[2];
// only one of the rest could be undefined
assert(! d1->needsReplacement() || ! d2->needsReplacement());
// if complete object destructor is missing...
if (d1->needsReplacement()) {
std::string gv2Name = d1->function->getName();
unsigned l = gv2Name.length();
gv2Name = gv2Name.replace(l-3, 1, "2");
Function* f1 = d1->getFunction();
assert(f1);
Function* f2 = module->getFunction(gv2Name);
assert(f2);
sd_print("Replacing %s with %s inside %s\n",
d1->function->getName().data(),
gv2Name.c_str(),
gv.getName().data());
f1->replaceAllUsesWith(f2);
replaced = true;
// if base object destructor is missing...
} else if (d2->needsReplacement()) {
std::string gv1Name = d2->function->getName();
unsigned l = gv1Name.length();
gv1Name = gv1Name.replace(l-3, 1, "1");
Function* f2 = d2->getFunction();
assert(f2);
Function* f1 = module->getFunction(gv1Name);
assert(f1);
sd_print("Replacing %s with %s inside %s\n",
d2->function->getName().data(),
gv1Name.c_str(),
gv.getName().data());
f2->replaceAllUsesWith(f1);
replaced = true;
}
}
}
return replaced;
}
示例9: 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);
//.........这里部分代码省略.........