本文整理汇总了C++中GlobalVariable::isConstant方法的典型用法代码示例。如果您正苦于以下问题:C++ GlobalVariable::isConstant方法的具体用法?C++ GlobalVariable::isConstant怎么用?C++ GlobalVariable::isConstant使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类GlobalVariable
的用法示例。
在下文中一共展示了GlobalVariable::isConstant方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: addDefinedSymbol
void LTOModule::addDefinedSymbol(GlobalValue *def, bool isFunction) {
// ignore all llvm.* symbols
if (def->getName().startswith("llvm."))
return;
// string is owned by _defines
SmallString<64> Buffer;
_mangler.getNameWithPrefix(Buffer, def, false);
// set alignment part log2() can have rounding errors
uint32_t align = def->getAlignment();
uint32_t attr = align ? CountTrailingZeros_32(def->getAlignment()) : 0;
// set permissions part
if (isFunction)
attr |= LTO_SYMBOL_PERMISSIONS_CODE;
else {
GlobalVariable *gv = dyn_cast<GlobalVariable>(def);
if (gv && gv->isConstant())
attr |= LTO_SYMBOL_PERMISSIONS_RODATA;
else
attr |= LTO_SYMBOL_PERMISSIONS_DATA;
}
// set definition part
if (def->hasWeakLinkage() || def->hasLinkOnceLinkage() ||
def->hasLinkerPrivateWeakLinkage() ||
def->hasLinkerPrivateWeakDefAutoLinkage())
attr |= LTO_SYMBOL_DEFINITION_WEAK;
else if (def->hasCommonLinkage())
attr |= LTO_SYMBOL_DEFINITION_TENTATIVE;
else
attr |= LTO_SYMBOL_DEFINITION_REGULAR;
// set scope part
if (def->hasHiddenVisibility())
attr |= LTO_SYMBOL_SCOPE_HIDDEN;
else if (def->hasProtectedVisibility())
attr |= LTO_SYMBOL_SCOPE_PROTECTED;
else if (def->hasExternalLinkage() || def->hasWeakLinkage() ||
def->hasLinkOnceLinkage() || def->hasCommonLinkage() ||
def->hasLinkerPrivateWeakLinkage())
attr |= LTO_SYMBOL_SCOPE_DEFAULT;
else if (def->hasLinkerPrivateWeakDefAutoLinkage())
attr |= LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN;
else
attr |= LTO_SYMBOL_SCOPE_INTERNAL;
// add to table of symbols
NameAndAttributes info;
StringSet::value_type &entry = _defines.GetOrCreateValue(Buffer);
entry.setValue(1);
StringRef Name = entry.getKey();
info.name = Name.data();
assert(info.name[Name.size()] == '\0');
info.attributes = (lto_symbol_attributes)attr;
_symbols.push_back(info);
}
示例2: addDefinedSymbol
void LTOModule::addDefinedSymbol(GlobalValue* def, Mangler &mangler,
bool isFunction)
{
// string is owned by _defines
const char* symbolName = ::strdup(mangler.getValueName(def).c_str());
// set alignment part log2() can have rounding errors
uint32_t align = def->getAlignment();
uint32_t attr = align ? CountTrailingZeros_32(def->getAlignment()) : 0;
// set permissions part
if ( isFunction )
attr |= LTO_SYMBOL_PERMISSIONS_CODE;
else {
GlobalVariable* gv = dyn_cast<GlobalVariable>(def);
if ( (gv != NULL) && gv->isConstant() )
attr |= LTO_SYMBOL_PERMISSIONS_RODATA;
else
attr |= LTO_SYMBOL_PERMISSIONS_DATA;
}
// set definition part
if ( def->hasWeakLinkage() || def->hasLinkOnceLinkage() ) {
// lvm bitcode does not differenciate between weak def data
// and tentative definitions!
// HACK HACK HACK
// C++ does not use tentative definitions, but does use weak symbols
// so guess that anything that looks like a C++ symbol is weak and others
// are tentative definitions
if ( (strncmp(symbolName, "__Z", 3) == 0) )
attr |= LTO_SYMBOL_DEFINITION_WEAK;
else {
attr |= LTO_SYMBOL_DEFINITION_TENTATIVE;
}
}
else {
attr |= LTO_SYMBOL_DEFINITION_REGULAR;
}
// set scope part
if ( def->hasHiddenVisibility() )
attr |= LTO_SYMBOL_SCOPE_HIDDEN;
else if ( def->hasExternalLinkage() || def->hasWeakLinkage() )
attr |= LTO_SYMBOL_SCOPE_DEFAULT;
else
attr |= LTO_SYMBOL_SCOPE_INTERNAL;
// add to table of symbols
NameAndAttributes info;
info.name = symbolName;
info.attributes = (lto_symbol_attributes)attr;
_symbols.push_back(info);
_defines[info.name] = 1;
}
示例3:
//
// Method: runOnModule()
//
// Description:
// Entry point for this LLVM pass.
//
// Return value:
// true - The module was modified.
// false - The module was not modified.
//
bool
BreakConstantStrings::runOnModule (Module & M) {
bool modified = false;
const Type * Int8Type = IntegerType::getInt8Ty(getGlobalContext());
//
// Scan through all the global variables in the module. Mark a variable as
// non-constant if:
// o) The variable is constant
// o) The variable is an array of characters (Int8Ty).
// o) The variable is not in a special section (e.g. debug info section).
// This ensures that we don't mess up debug information or other special
// strings within the code.
//
Module::global_iterator i,e;
for (i = M.global_begin(), e = M.global_end(); i != e; ++i) {
GlobalVariable * GV = i;
//
// All global variables are pointer types. Find the type of what the
// global variable pointer is pointing at.
//
if (GV->isConstant() && (!GV->hasSection())) {
const PointerType * PT = dyn_cast<PointerType>(GV->getType());
if (const ArrayType * AT = dyn_cast<ArrayType>(PT->getElementType())) {
if (AT->getElementType() == Int8Type) {
modified = true;
++GVChanges;
GV->setConstant (false);
}
}
}
}
return modified;
}
示例4: 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;
}
示例5: runOnModule
bool ConstantMerge::runOnModule(Module &M) {
TD = getAnalysisIfAvailable<TargetData>();
// Find all the globals that are marked "used". These cannot be merged.
SmallPtrSet<const GlobalValue*, 8> UsedGlobals;
FindUsedValues(M.getGlobalVariable("llvm.used"), UsedGlobals);
FindUsedValues(M.getGlobalVariable("llvm.compiler.used"), UsedGlobals);
// Map unique <constants, has-unknown-alignment> pairs to globals. We don't
// want to merge globals of unknown alignment with those of explicit
// alignment. If we have TargetData, we always know the alignment.
DenseMap<PointerIntPair<Constant*, 1, bool>, GlobalVariable*> CMap;
// Replacements - This vector contains a list of replacements to perform.
SmallVector<std::pair<GlobalVariable*, GlobalVariable*>, 32> Replacements;
bool MadeChange = false;
// Iterate constant merging while we are still making progress. Merging two
// constants together may allow us to merge other constants together if the
// second level constants have initializers which point to the globals that
// were just merged.
while (1) {
// First: Find the canonical constants others will be merged with.
for (Module::global_iterator GVI = M.global_begin(), E = M.global_end();
GVI != E; ) {
GlobalVariable *GV = GVI++;
// If this GV is dead, remove it.
GV->removeDeadConstantUsers();
if (GV->use_empty() && GV->hasLocalLinkage()) {
GV->eraseFromParent();
continue;
}
// Only process constants with initializers in the default address space.
if (!GV->isConstant() || !GV->hasDefinitiveInitializer() ||
GV->getType()->getAddressSpace() != 0 || GV->hasSection() ||
// Don't touch values marked with attribute(used).
UsedGlobals.count(GV))
continue;
// This transformation is legal for weak ODR globals in the sense it
// doesn't change semantics, but we really don't want to perform it
// anyway; it's likely to pessimize code generation, and some tools
// (like the Darwin linker in cases involving CFString) don't expect it.
if (GV->isWeakForLinker())
continue;
Constant *Init = GV->getInitializer();
// Check to see if the initializer is already known.
PointerIntPair<Constant*, 1, bool> Pair(Init, hasKnownAlignment(GV));
GlobalVariable *&Slot = CMap[Pair];
// If this is the first constant we find or if the old one is local,
// replace with the current one. If the current is externally visible
// it cannot be replace, but can be the canonical constant we merge with.
if (Slot == 0 || IsBetterCannonical(*GV, *Slot))
Slot = GV;
}
// Second: identify all globals that can be merged together, filling in
// the Replacements vector. We cannot do the replacement in this pass
// because doing so may cause initializers of other globals to be rewritten,
// invalidating the Constant* pointers in CMap.
for (Module::global_iterator GVI = M.global_begin(), E = M.global_end();
GVI != E; ) {
GlobalVariable *GV = GVI++;
// Only process constants with initializers in the default address space.
if (!GV->isConstant() || !GV->hasDefinitiveInitializer() ||
GV->getType()->getAddressSpace() != 0 || GV->hasSection() ||
// Don't touch values marked with attribute(used).
UsedGlobals.count(GV))
continue;
// We can only replace constant with local linkage.
if (!GV->hasLocalLinkage())
continue;
Constant *Init = GV->getInitializer();
// Check to see if the initializer is already known.
PointerIntPair<Constant*, 1, bool> Pair(Init, hasKnownAlignment(GV));
GlobalVariable *Slot = CMap[Pair];
if (!Slot || Slot == GV)
continue;
if (!Slot->hasUnnamedAddr() && !GV->hasUnnamedAddr())
continue;
if (!GV->hasUnnamedAddr())
Slot->setUnnamedAddr(false);
// Make all uses of the duplicate constant use the canonical version.
Replacements.push_back(std::make_pair(GV, Slot));
}
//.........这里部分代码省略.........
示例6: runOnModule
bool ConstantMerge::runOnModule(Module &M) {
// Find all the globals that are marked "used". These cannot be merged.
SmallPtrSet<const GlobalValue*, 8> UsedGlobals;
FindUsedValues(M.getGlobalVariable("llvm.used"), UsedGlobals);
FindUsedValues(M.getGlobalVariable("llvm.compiler.used"), UsedGlobals);
// Map unique constant/section pairs to globals. We don't want to merge
// globals in different sections.
DenseMap<Constant*, GlobalVariable*> CMap;
// Replacements - This vector contains a list of replacements to perform.
SmallVector<std::pair<GlobalVariable*, GlobalVariable*>, 32> Replacements;
bool MadeChange = false;
// Iterate constant merging while we are still making progress. Merging two
// constants together may allow us to merge other constants together if the
// second level constants have initializers which point to the globals that
// were just merged.
while (1) {
// First pass: identify all globals that can be merged together, filling in
// the Replacements vector. We cannot do the replacement in this pass
// because doing so may cause initializers of other globals to be rewritten,
// invalidating the Constant* pointers in CMap.
//
for (Module::global_iterator GVI = M.global_begin(), E = M.global_end();
GVI != E; ) {
GlobalVariable *GV = GVI++;
// If this GV is dead, remove it.
GV->removeDeadConstantUsers();
if (GV->use_empty() && GV->hasLocalLinkage()) {
GV->eraseFromParent();
continue;
}
// Only process constants with initializers in the default addres space.
if (!GV->isConstant() ||!GV->hasDefinitiveInitializer() ||
GV->getType()->getAddressSpace() != 0 || !GV->getSection().empty() ||
// Don't touch values marked with attribute(used).
UsedGlobals.count(GV))
continue;
Constant *Init = GV->getInitializer();
// Check to see if the initializer is already known.
GlobalVariable *&Slot = CMap[Init];
if (Slot == 0) { // Nope, add it to the map.
Slot = GV;
} else if (GV->hasLocalLinkage()) { // Yup, this is a duplicate!
// Make all uses of the duplicate constant use the canonical version.
Replacements.push_back(std::make_pair(GV, Slot));
}
}
if (Replacements.empty())
return MadeChange;
CMap.clear();
// Now that we have figured out which replacements must be made, do them all
// now. This avoid invalidating the pointers in CMap, which are unneeded
// now.
for (unsigned i = 0, e = Replacements.size(); i != e; ++i) {
// Eliminate any uses of the dead global.
Replacements[i].first->replaceAllUsesWith(Replacements[i].second);
// Delete the global value from the module.
Replacements[i].first->eraseFromParent();
}
NumMerged += Replacements.size();
Replacements.clear();
}
}
示例7: runOnModule
bool GenericToNVVM::runOnModule(Module &M) {
// Create a clone of each global variable that has the default address space.
// The clone is created with the global address space specifier, and the pair
// of original global variable and its clone is placed in the GVMap for later
// use.
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
I != E;) {
GlobalVariable *GV = &*I++;
if (GV->getType()->getAddressSpace() == llvm::ADDRESS_SPACE_GENERIC &&
!llvm::isTexture(*GV) && !llvm::isSurface(*GV) &&
!llvm::isSampler(*GV) && !GV->getName().startswith("llvm.")) {
GlobalVariable *NewGV = new GlobalVariable(
M, GV->getValueType(), GV->isConstant(),
GV->getLinkage(),
GV->hasInitializer() ? GV->getInitializer() : nullptr,
"", GV, GV->getThreadLocalMode(), llvm::ADDRESS_SPACE_GLOBAL);
NewGV->copyAttributesFrom(GV);
GVMap[GV] = NewGV;
}
}
// Return immediately, if every global variable has a specific address space
// specifier.
if (GVMap.empty()) {
return false;
}
// Walk through the instructions in function defitinions, and replace any use
// of original global variables in GVMap with a use of the corresponding
// copies in GVMap. If necessary, promote constants to instructions.
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
if (I->isDeclaration()) {
continue;
}
IRBuilder<> Builder(I->getEntryBlock().getFirstNonPHIOrDbg());
for (Function::iterator BBI = I->begin(), BBE = I->end(); BBI != BBE;
++BBI) {
for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
++II) {
for (unsigned i = 0, e = II->getNumOperands(); i < e; ++i) {
Value *Operand = II->getOperand(i);
if (isa<Constant>(Operand)) {
II->setOperand(
i, remapConstant(&M, &*I, cast<Constant>(Operand), Builder));
}
}
}
}
ConstantToValueMap.clear();
}
// Copy GVMap over to a standard value map.
ValueToValueMapTy VM;
for (auto I = GVMap.begin(), E = GVMap.end(); I != E; ++I)
VM[I->first] = I->second;
// Walk through the metadata section and update the debug information
// associated with the global variables in the default address space.
for (NamedMDNode &I : M.named_metadata()) {
remapNamedMDNode(VM, &I);
}
// Walk through the global variable initializers, and replace any use of
// original global variables in GVMap with a use of the corresponding copies
// in GVMap. The copies need to be bitcast to the original global variable
// types, as we cannot use cvta in global variable initializers.
for (GVMapTy::iterator I = GVMap.begin(), E = GVMap.end(); I != E;) {
GlobalVariable *GV = I->first;
GlobalVariable *NewGV = I->second;
// Remove GV from the map so that it can be RAUWed. Note that
// DenseMap::erase() won't invalidate any iterators but this one.
auto Next = std::next(I);
GVMap.erase(I);
I = Next;
Constant *BitCastNewGV = ConstantExpr::getPointerCast(NewGV, GV->getType());
// At this point, the remaining uses of GV should be found only in global
// variable initializers, as other uses have been already been removed
// while walking through the instructions in function definitions.
GV->replaceAllUsesWith(BitCastNewGV);
std::string Name = GV->getName();
GV->eraseFromParent();
NewGV->setName(Name);
}
assert(GVMap.empty() && "Expected it to be empty by now");
return true;
}
示例8: insertGlobalRedzones
// This function replaces all global variables with new variables that have
// trailing redzones. It also creates a function that poisons
// redzones and inserts this function into llvm.global_ctors.
bool AddressSanitizer::insertGlobalRedzones(Module &M) {
SmallVector<GlobalVariable *, 16> GlobalsToChange;
for (Module::GlobalListType::iterator G = M.global_begin(),
E = M.global_end(); G != E; ++G) {
if (ShouldInstrumentGlobal(G))
GlobalsToChange.push_back(G);
}
size_t n = GlobalsToChange.size();
if (n == 0) return false;
// A global is described by a structure
// size_t beg;
// size_t size;
// size_t size_with_redzone;
// const char *name;
// size_t has_dynamic_init;
// We initialize an array of such structures and pass it to a run-time call.
StructType *GlobalStructTy = StructType::get(IntptrTy, IntptrTy,
IntptrTy, IntptrTy,
IntptrTy, NULL);
SmallVector<Constant *, 16> Initializers(n), DynamicInit;
IRBuilder<> IRB(CtorInsertBefore);
if (ClInitializers)
FindDynamicInitializers(M);
// The addresses of the first and last dynamically initialized globals in
// this TU. Used in initialization order checking.
Value *FirstDynamic = 0, *LastDynamic = 0;
for (size_t i = 0; i < n; i++) {
GlobalVariable *G = GlobalsToChange[i];
PointerType *PtrTy = cast<PointerType>(G->getType());
Type *Ty = PtrTy->getElementType();
uint64_t SizeInBytes = TD->getTypeAllocSize(Ty);
uint64_t RightRedzoneSize = RedzoneSize +
(RedzoneSize - (SizeInBytes % RedzoneSize));
Type *RightRedZoneTy = ArrayType::get(IRB.getInt8Ty(), RightRedzoneSize);
// Determine whether this global should be poisoned in initialization.
bool GlobalHasDynamicInitializer = HasDynamicInitializer(G);
// Don't check initialization order if this global is blacklisted.
GlobalHasDynamicInitializer &= !BL->isInInit(*G);
StructType *NewTy = StructType::get(Ty, RightRedZoneTy, NULL);
Constant *NewInitializer = ConstantStruct::get(
NewTy, G->getInitializer(),
Constant::getNullValue(RightRedZoneTy), NULL);
SmallString<2048> DescriptionOfGlobal = G->getName();
DescriptionOfGlobal += " (";
DescriptionOfGlobal += M.getModuleIdentifier();
DescriptionOfGlobal += ")";
GlobalVariable *Name = createPrivateGlobalForString(M, DescriptionOfGlobal);
// Create a new global variable with enough space for a redzone.
GlobalVariable *NewGlobal = new GlobalVariable(
M, NewTy, G->isConstant(), G->getLinkage(),
NewInitializer, "", G, G->getThreadLocalMode());
NewGlobal->copyAttributesFrom(G);
NewGlobal->setAlignment(RedzoneSize);
Value *Indices2[2];
Indices2[0] = IRB.getInt32(0);
Indices2[1] = IRB.getInt32(0);
G->replaceAllUsesWith(
ConstantExpr::getGetElementPtr(NewGlobal, Indices2, true));
NewGlobal->takeName(G);
G->eraseFromParent();
Initializers[i] = ConstantStruct::get(
GlobalStructTy,
ConstantExpr::getPointerCast(NewGlobal, IntptrTy),
ConstantInt::get(IntptrTy, SizeInBytes),
ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize),
ConstantExpr::getPointerCast(Name, IntptrTy),
ConstantInt::get(IntptrTy, GlobalHasDynamicInitializer),
NULL);
// Populate the first and last globals declared in this TU.
if (ClInitializers && GlobalHasDynamicInitializer) {
LastDynamic = ConstantExpr::getPointerCast(NewGlobal, IntptrTy);
if (FirstDynamic == 0)
FirstDynamic = LastDynamic;
}
DEBUG(dbgs() << "NEW GLOBAL:\n" << *NewGlobal);
}
ArrayType *ArrayOfGlobalStructTy = ArrayType::get(GlobalStructTy, n);
GlobalVariable *AllGlobals = new GlobalVariable(
M, ArrayOfGlobalStructTy, false, GlobalVariable::PrivateLinkage,
ConstantArray::get(ArrayOfGlobalStructTy, Initializers), "");
//.........这里部分代码省略.........
示例9: insertGlobalRedzones
//.........这里部分代码省略.........
continue;
}
}
GlobalsToChange.push_back(G);
}
size_t n = GlobalsToChange.size();
if (n == 0) return false;
// A global is described by a structure
// size_t beg;
// size_t size;
// size_t size_with_redzone;
// const char *name;
// We initialize an array of such structures and pass it to a run-time call.
StructType *GlobalStructTy = StructType::get(IntptrTy, IntptrTy,
IntptrTy, IntptrTy, NULL);
SmallVector<Constant *, 16> Initializers(n);
IRBuilder<> IRB(CtorInsertBefore);
for (size_t i = 0; i < n; i++) {
GlobalVariable *G = GlobalsToChange[i];
PointerType *PtrTy = cast<PointerType>(G->getType());
Type *Ty = PtrTy->getElementType();
uint64_t SizeInBytes = TD->getTypeStoreSizeInBits(Ty) / 8;
uint64_t RightRedzoneSize = RedzoneSize +
(RedzoneSize - (SizeInBytes % RedzoneSize));
Type *RightRedZoneTy = ArrayType::get(IRB.getInt8Ty(), RightRedzoneSize);
StructType *NewTy = StructType::get(Ty, RightRedZoneTy, NULL);
Constant *NewInitializer = ConstantStruct::get(
NewTy, G->getInitializer(),
Constant::getNullValue(RightRedZoneTy), NULL);
SmallString<2048> DescriptionOfGlobal = G->getName();
DescriptionOfGlobal += " (";
DescriptionOfGlobal += M.getModuleIdentifier();
DescriptionOfGlobal += ")";
GlobalVariable *Name = createPrivateGlobalForString(M, DescriptionOfGlobal);
// Create a new global variable with enough space for a redzone.
GlobalVariable *NewGlobal = new GlobalVariable(
M, NewTy, G->isConstant(), G->getLinkage(),
NewInitializer, "", G, G->isThreadLocal());
NewGlobal->copyAttributesFrom(G);
NewGlobal->setAlignment(RedzoneSize);
Value *Indices2[2];
Indices2[0] = IRB.getInt32(0);
Indices2[1] = IRB.getInt32(0);
G->replaceAllUsesWith(
ConstantExpr::getGetElementPtr(NewGlobal, Indices2, true));
NewGlobal->takeName(G);
G->eraseFromParent();
Initializers[i] = ConstantStruct::get(
GlobalStructTy,
ConstantExpr::getPointerCast(NewGlobal, IntptrTy),
ConstantInt::get(IntptrTy, SizeInBytes),
ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize),
ConstantExpr::getPointerCast(Name, IntptrTy),
NULL);
DEBUG(dbgs() << "NEW GLOBAL:\n" << *NewGlobal);
}
ArrayType *ArrayOfGlobalStructTy = ArrayType::get(GlobalStructTy, n);
GlobalVariable *AllGlobals = new GlobalVariable(
M, ArrayOfGlobalStructTy, false, GlobalVariable::PrivateLinkage,
ConstantArray::get(ArrayOfGlobalStructTy, Initializers), "");
Function *AsanRegisterGlobals = cast<Function>(M.getOrInsertFunction(
kAsanRegisterGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy, NULL));
AsanRegisterGlobals->setLinkage(Function::ExternalLinkage);
IRB.CreateCall2(AsanRegisterGlobals,
IRB.CreatePointerCast(AllGlobals, IntptrTy),
ConstantInt::get(IntptrTy, n));
// We also need to unregister globals at the end, e.g. when a shared library
// gets closed.
Function *AsanDtorFunction = Function::Create(
FunctionType::get(Type::getVoidTy(*C), false),
GlobalValue::InternalLinkage, kAsanModuleDtorName, &M);
BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction);
IRBuilder<> IRB_Dtor(ReturnInst::Create(*C, AsanDtorBB));
Function *AsanUnregisterGlobals = cast<Function>(M.getOrInsertFunction(
kAsanUnregisterGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy, NULL));
AsanUnregisterGlobals->setLinkage(Function::ExternalLinkage);
IRB_Dtor.CreateCall2(AsanUnregisterGlobals,
IRB.CreatePointerCast(AllGlobals, IntptrTy),
ConstantInt::get(IntptrTy, n));
appendToGlobalDtors(M, AsanDtorFunction, kAsanCtorAndCtorPriority);
DEBUG(dbgs() << M);
return true;
}
示例10: emit_global_to_llvm
/// emit_global_to_llvm - Emit the specified VAR_DECL or aggregate CONST_DECL to
/// LLVM as a global variable. This function implements the end of
/// assemble_variable.
void emit_global_to_llvm(tree decl) {
if (errorcount || sorrycount) return;
// FIXME: Support alignment on globals: DECL_ALIGN.
// FIXME: DECL_PRESERVE_P indicates the var is marked with attribute 'used'.
// Global register variables don't turn into LLVM GlobalVariables.
if (TREE_CODE(decl) == VAR_DECL && DECL_REGISTER(decl))
return;
timevar_push(TV_LLVM_GLOBALS);
// Get or create the global variable now.
GlobalVariable *GV = cast<GlobalVariable>(DECL_LLVM(decl));
// Convert the initializer over.
Constant *Init;
if (DECL_INITIAL(decl) == 0 || DECL_INITIAL(decl) == error_mark_node) {
// This global should be zero initialized. Reconvert the type in case the
// forward def of the global and the real def differ in type (e.g. declared
// as 'int A[]', and defined as 'int A[100]').
Init = Constant::getNullValue(ConvertType(TREE_TYPE(decl)));
} else {
assert((TREE_CONSTANT(DECL_INITIAL(decl)) ||
TREE_CODE(DECL_INITIAL(decl)) == STRING_CST) &&
"Global initializer should be constant!");
// Temporarily set an initializer for the global, so we don't infinitely
// recurse. If we don't do this, we can hit cases where we see "oh a global
// with an initializer hasn't been initialized yet, call emit_global_to_llvm
// on it". When constructing the initializer it might refer to itself.
// this can happen for things like void *G = &G;
//
GV->setInitializer(UndefValue::get(GV->getType()->getElementType()));
Init = TreeConstantToLLVM::Convert(DECL_INITIAL(decl));
}
// If we had a forward definition that has a type that disagrees with our
// initializer, insert a cast now. This sort of thing occurs when we have a
// global union, and the LLVM type followed a union initializer that is
// different from the union element used for the type.
if (GV->getType()->getElementType() != Init->getType()) {
GV->removeFromParent();
GlobalVariable *NGV = new GlobalVariable(Init->getType(), GV->isConstant(),
GlobalValue::ExternalLinkage, 0,
GV->getName(), TheModule);
GV->replaceAllUsesWith(ConstantExpr::getBitCast(NGV, GV->getType()));
delete GV;
SET_DECL_LLVM(decl, NGV);
GV = NGV;
}
// Set the initializer.
GV->setInitializer(Init);
// Set thread local (TLS)
if (TREE_CODE(decl) == VAR_DECL && DECL_THREAD_LOCAL(decl))
GV->setThreadLocal(true);
// Set the linkage.
if (!TREE_PUBLIC(decl)) {
GV->setLinkage(GlobalValue::InternalLinkage);
} else if (DECL_WEAK(decl) || DECL_ONE_ONLY(decl) ||
(DECL_COMMON(decl) && // DECL_COMMON is only meaningful if no init
(!DECL_INITIAL(decl) || DECL_INITIAL(decl) == error_mark_node))) {
// llvm-gcc also includes DECL_VIRTUAL_P here.
GV->setLinkage(GlobalValue::WeakLinkage);
} else if (DECL_COMDAT(decl)) {
GV->setLinkage(GlobalValue::LinkOnceLinkage);
}
#ifdef TARGET_ADJUST_LLVM_LINKAGE
TARGET_ADJUST_LLVM_LINKAGE(GV,decl);
#endif /* TARGET_ADJUST_LLVM_LINKAGE */
// Handle visibility style
if (TREE_PUBLIC(decl)) {
if (DECL_VISIBILITY(decl) == VISIBILITY_HIDDEN)
GV->setVisibility(GlobalValue::HiddenVisibility);
else if (DECL_VISIBILITY(decl) == VISIBILITY_PROTECTED)
GV->setVisibility(GlobalValue::ProtectedVisibility);
}
// Set the section for the global.
if (TREE_CODE(decl) == VAR_DECL || TREE_CODE(decl) == CONST_DECL) {
if (DECL_SECTION_NAME(decl)) {
GV->setSection(TREE_STRING_POINTER(DECL_SECTION_NAME(decl)));
#ifdef LLVM_IMPLICIT_TARGET_GLOBAL_VAR_SECTION
} else if (const char *Section =
LLVM_IMPLICIT_TARGET_GLOBAL_VAR_SECTION(decl)) {
GV->setSection(Section);
#endif
}
// Set the alignment for the global if one of the following condition is met
// 1) DECL_ALIGN_UNIT does not match alignment as per ABI specification
// 2) DECL_ALIGN is set by user.
//.........这里部分代码省略.........