Eugene Zelenko | dc6cb60 | 2017-05-10 23:41:30 +0000 | [diff] [blame] | 1 | //===- Module.cpp - Implement the Module class ----------------------------===// |
Misha Brukman | fd93908 | 2005-04-21 23:48:37 +0000 | [diff] [blame] | 2 | // |
John Criswell | b576c94 | 2003-10-20 19:43:21 +0000 | [diff] [blame] | 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
Chris Lattner | 4ee451d | 2007-12-29 20:36:04 +0000 | [diff] [blame] | 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
Misha Brukman | fd93908 | 2005-04-21 23:48:37 +0000 | [diff] [blame] | 7 | // |
John Criswell | b576c94 | 2003-10-20 19:43:21 +0000 | [diff] [blame] | 8 | //===----------------------------------------------------------------------===// |
Chris Lattner | 0095054 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 9 | // |
Chandler Carruth | c2c50cd | 2013-01-02 09:10:48 +0000 | [diff] [blame] | 10 | // This file implements the Module class for the IR library. |
Chris Lattner | 0095054 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
Chandler Carruth | e3e43d9 | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 14 | #include "llvm/IR/Module.h" |
Chandler Carruth | d04a8d4 | 2012-12-03 16:50:05 +0000 | [diff] [blame] | 15 | #include "SymbolTableListTraitsImpl.h" |
Caroline Tice | a53c520 | 2018-09-21 18:41:31 +0000 | [diff] [blame] | 16 | #include "llvm/ADT/Optional.h" |
Teresa Johnson | 89c5c63 | 2016-04-20 14:39:45 +0000 | [diff] [blame] | 17 | #include "llvm/ADT/SmallPtrSet.h" |
Chandler Carruth | d04a8d4 | 2012-12-03 16:50:05 +0000 | [diff] [blame] | 18 | #include "llvm/ADT/SmallString.h" |
Eugene Zelenko | dc6cb60 | 2017-05-10 23:41:30 +0000 | [diff] [blame] | 19 | #include "llvm/ADT/SmallVector.h" |
| 20 | #include "llvm/ADT/StringMap.h" |
| 21 | #include "llvm/ADT/StringRef.h" |
| 22 | #include "llvm/ADT/Twine.h" |
| 23 | #include "llvm/IR/Attributes.h" |
| 24 | #include "llvm/IR/Comdat.h" |
Chandler Carruth | 0b8c9a8 | 2013-01-02 11:36:10 +0000 | [diff] [blame] | 25 | #include "llvm/IR/Constants.h" |
Eugene Zelenko | dc6cb60 | 2017-05-10 23:41:30 +0000 | [diff] [blame] | 26 | #include "llvm/IR/DataLayout.h" |
Adrian Prantl | 48bb8b4 | 2016-04-08 22:43:03 +0000 | [diff] [blame] | 27 | #include "llvm/IR/DebugInfoMetadata.h" |
Chandler Carruth | e3e43d9 | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 28 | #include "llvm/IR/DerivedTypes.h" |
Eugene Zelenko | dc6cb60 | 2017-05-10 23:41:30 +0000 | [diff] [blame] | 29 | #include "llvm/IR/Function.h" |
Chandler Carruth | e3e43d9 | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 30 | #include "llvm/IR/GVMaterializer.h" |
Eugene Zelenko | dc6cb60 | 2017-05-10 23:41:30 +0000 | [diff] [blame] | 31 | #include "llvm/IR/GlobalAlias.h" |
| 32 | #include "llvm/IR/GlobalIFunc.h" |
| 33 | #include "llvm/IR/GlobalValue.h" |
| 34 | #include "llvm/IR/GlobalVariable.h" |
Chandler Carruth | 0b8c9a8 | 2013-01-02 11:36:10 +0000 | [diff] [blame] | 35 | #include "llvm/IR/LLVMContext.h" |
Eugene Zelenko | dc6cb60 | 2017-05-10 23:41:30 +0000 | [diff] [blame] | 36 | #include "llvm/IR/Metadata.h" |
Eugene Zelenko | dc6cb60 | 2017-05-10 23:41:30 +0000 | [diff] [blame] | 37 | #include "llvm/IR/SymbolTableListTraits.h" |
| 38 | #include "llvm/IR/Type.h" |
Rafael Espindola | eee41db | 2014-12-03 07:18:23 +0000 | [diff] [blame] | 39 | #include "llvm/IR/TypeFinder.h" |
Eugene Zelenko | dc6cb60 | 2017-05-10 23:41:30 +0000 | [diff] [blame] | 40 | #include "llvm/IR/Value.h" |
| 41 | #include "llvm/IR/ValueSymbolTable.h" |
| 42 | #include "llvm/Pass.h" |
| 43 | #include "llvm/Support/Casting.h" |
| 44 | #include "llvm/Support/CodeGen.h" |
Peter Collingbourne | 76c218e | 2016-11-09 17:49:19 +0000 | [diff] [blame] | 45 | #include "llvm/Support/Error.h" |
Peter Collingbourne | 5498e18 | 2016-11-08 06:03:43 +0000 | [diff] [blame] | 46 | #include "llvm/Support/MemoryBuffer.h" |
JF Bastien | b4840d7 | 2014-06-25 15:21:42 +0000 | [diff] [blame] | 47 | #include "llvm/Support/Path.h" |
| 48 | #include "llvm/Support/RandomNumberGenerator.h" |
Alex Lorenz | 6592c09 | 2018-12-14 01:14:10 +0000 | [diff] [blame] | 49 | #include "llvm/Support/VersionTuple.h" |
Chris Lattner | 7e70829 | 2002-06-25 16:13:24 +0000 | [diff] [blame] | 50 | #include <algorithm> |
Eugene Zelenko | dc6cb60 | 2017-05-10 23:41:30 +0000 | [diff] [blame] | 51 | #include <cassert> |
| 52 | #include <cstdint> |
| 53 | #include <memory> |
| 54 | #include <utility> |
| 55 | #include <vector> |
Hans Wennborg | 4d651e4 | 2015-10-06 23:24:35 +0000 | [diff] [blame] | 56 | |
Chris Lattner | 31f8499 | 2003-11-21 20:23:48 +0000 | [diff] [blame] | 57 | using namespace llvm; |
Brian Gaeke | d0fde30 | 2003-11-11 22:41:34 +0000 | [diff] [blame] | 58 | |
Chris Lattner | 6083782 | 2003-12-31 08:43:01 +0000 | [diff] [blame] | 59 | //===----------------------------------------------------------------------===// |
Misha Brukman | af76cfb | 2004-04-21 18:27:56 +0000 | [diff] [blame] | 60 | // Methods to implement the globals and functions lists. |
Chris Lattner | 6083782 | 2003-12-31 08:43:01 +0000 | [diff] [blame] | 61 | // |
| 62 | |
Chris Lattner | 7e70829 | 2002-06-25 16:13:24 +0000 | [diff] [blame] | 63 | // Explicit instantiations of SymbolTableListTraits since some of the methods |
Chris Lattner | cc041ba | 2006-01-24 04:13:11 +0000 | [diff] [blame] | 64 | // are not in the public header file. |
Duncan P. N. Exon Smith | 2a8bcfa | 2015-10-07 20:05:10 +0000 | [diff] [blame] | 65 | template class llvm::SymbolTableListTraits<Function>; |
| 66 | template class llvm::SymbolTableListTraits<GlobalVariable>; |
| 67 | template class llvm::SymbolTableListTraits<GlobalAlias>; |
Dmitry Polukhin | ba49223 | 2016-04-07 12:32:19 +0000 | [diff] [blame] | 68 | template class llvm::SymbolTableListTraits<GlobalIFunc>; |
Chris Lattner | 0095054 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 69 | |
Chris Lattner | 6083782 | 2003-12-31 08:43:01 +0000 | [diff] [blame] | 70 | //===----------------------------------------------------------------------===// |
| 71 | // Primitive Module methods. |
| 72 | // |
Chris Lattner | dd6dfbc | 2001-10-13 06:58:40 +0000 | [diff] [blame] | 73 | |
Rafael Espindola | aab87fe | 2014-02-25 20:01:08 +0000 | [diff] [blame] | 74 | Module::Module(StringRef MID, LLVMContext &C) |
Teresa Johnson | 0060160 | 2016-02-10 21:55:02 +0000 | [diff] [blame] | 75 | : Context(C), Materializer(), ModuleID(MID), SourceFileName(MID), DL("") { |
Reid Spencer | ef9b9a7 | 2007-02-05 20:47:22 +0000 | [diff] [blame] | 76 | ValSymTab = new ValueSymbolTable(); |
Dan Gohman | 17aa92c | 2010-07-21 23:38:33 +0000 | [diff] [blame] | 77 | NamedMDSymTab = new StringMap<NamedMDNode *>(); |
Owen Anderson | 30268be | 2010-09-08 18:03:32 +0000 | [diff] [blame] | 78 | Context.addModule(this); |
Chris Lattner | 0095054 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 79 | } |
| 80 | |
| 81 | Module::~Module() { |
Owen Anderson | 30268be | 2010-09-08 18:03:32 +0000 | [diff] [blame] | 82 | Context.removeModule(this); |
Chris Lattner | 0095054 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 83 | dropAllReferences(); |
Chris Lattner | 7e70829 | 2002-06-25 16:13:24 +0000 | [diff] [blame] | 84 | GlobalList.clear(); |
Chris Lattner | 7e70829 | 2002-06-25 16:13:24 +0000 | [diff] [blame] | 85 | FunctionList.clear(); |
Anton Korobeynikov | 8b0a8c8 | 2007-04-25 14:27:10 +0000 | [diff] [blame] | 86 | AliasList.clear(); |
Dmitry Polukhin | ba49223 | 2016-04-07 12:32:19 +0000 | [diff] [blame] | 87 | IFuncList.clear(); |
Devang Patel | 28bc9d8 | 2009-07-29 17:16:17 +0000 | [diff] [blame] | 88 | NamedMDList.clear(); |
Reid Spencer | 78d033e | 2007-01-06 07:24:44 +0000 | [diff] [blame] | 89 | delete ValSymTab; |
Dan Gohman | 17aa92c | 2010-07-21 23:38:33 +0000 | [diff] [blame] | 90 | delete static_cast<StringMap<NamedMDNode *> *>(NamedMDSymTab); |
Chris Lattner | 0095054 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 91 | } |
| 92 | |
Serge Guelton | fbec1c9 | 2017-07-12 08:03:44 +0000 | [diff] [blame] | 93 | std::unique_ptr<RandomNumberGenerator> Module::createRNG(const Pass* P) const { |
JF Bastien | 544f63e | 2014-12-17 18:12:10 +0000 | [diff] [blame] | 94 | SmallString<32> Salt(P->getPassName()); |
| 95 | |
| 96 | // This RNG is guaranteed to produce the same random stream only |
| 97 | // when the Module ID and thus the input filename is the same. This |
| 98 | // might be problematic if the input filename extension changes |
| 99 | // (e.g. from .c to .bc or .ll). |
| 100 | // |
| 101 | // We could store this salt in NamedMetadata, but this would make |
| 102 | // the parameter non-const. This would unfortunately make this |
| 103 | // interface unusable by any Machine passes, since they only have a |
| 104 | // const reference to their IR Module. Alternatively we can always |
| 105 | // store salt metadata from the Module constructor. |
| 106 | Salt += sys::path::filename(getModuleIdentifier()); |
| 107 | |
Serge Guelton | 624678f | 2017-07-18 08:36:22 +0000 | [diff] [blame] | 108 | return std::unique_ptr<RandomNumberGenerator>(new RandomNumberGenerator(Salt)); |
JF Bastien | 544f63e | 2014-12-17 18:12:10 +0000 | [diff] [blame] | 109 | } |
| 110 | |
Daniel Dunbar | f56ec64 | 2009-03-06 22:04:43 +0000 | [diff] [blame] | 111 | /// getNamedValue - Return the first global value in the module with |
| 112 | /// the specified name, of arbitrary type. This method returns null |
| 113 | /// if a global with the specified name is not found. |
Daniel Dunbar | 2928c83 | 2009-11-06 10:58:06 +0000 | [diff] [blame] | 114 | GlobalValue *Module::getNamedValue(StringRef Name) const { |
Daniel Dunbar | f56ec64 | 2009-03-06 22:04:43 +0000 | [diff] [blame] | 115 | return cast_or_null<GlobalValue>(getValueSymbolTable().lookup(Name)); |
| 116 | } |
| 117 | |
Chris Lattner | 0811347 | 2009-12-29 09:01:33 +0000 | [diff] [blame] | 118 | /// getMDKindID - Return a unique non-zero ID for the specified metadata kind. |
| 119 | /// This ID is uniqued across modules in the current LLVMContext. |
| 120 | unsigned Module::getMDKindID(StringRef Name) const { |
| 121 | return Context.getMDKindID(Name); |
| 122 | } |
| 123 | |
| 124 | /// getMDKindNames - Populate client supplied SmallVector with the name for |
| 125 | /// custom metadata IDs registered in this LLVMContext. ID #0 is not used, |
| 126 | /// so it is filled in as an empty string. |
| 127 | void Module::getMDKindNames(SmallVectorImpl<StringRef> &Result) const { |
| 128 | return Context.getMDKindNames(Result); |
| 129 | } |
| 130 | |
Sanjoy Das | 5b674c0 | 2015-09-24 19:14:18 +0000 | [diff] [blame] | 131 | void Module::getOperandBundleTags(SmallVectorImpl<StringRef> &Result) const { |
| 132 | return Context.getOperandBundleTags(Result); |
| 133 | } |
Chris Lattner | 0811347 | 2009-12-29 09:01:33 +0000 | [diff] [blame] | 134 | |
Chris Lattner | 6083782 | 2003-12-31 08:43:01 +0000 | [diff] [blame] | 135 | //===----------------------------------------------------------------------===// |
| 136 | // Methods for easy access to the functions in the module. |
| 137 | // |
| 138 | |
Reid Spencer | ef9b9a7 | 2007-02-05 20:47:22 +0000 | [diff] [blame] | 139 | // getOrInsertFunction - Look up the specified function in the module symbol |
| 140 | // table. If it does not exist, add a prototype for the function and return |
| 141 | // it. This is nice because it allows most passes to get away with not handling |
| 142 | // the symbol table directly for this common task. |
| 143 | // |
Reid Kleckner | 6707770 | 2017-03-21 16:57:19 +0000 | [diff] [blame] | 144 | Constant *Module::getOrInsertFunction(StringRef Name, FunctionType *Ty, |
| 145 | AttributeList AttributeList) { |
Reid Spencer | ef9b9a7 | 2007-02-05 20:47:22 +0000 | [diff] [blame] | 146 | // See if we have a definition for the specified function already. |
Daniel Dunbar | f56ec64 | 2009-03-06 22:04:43 +0000 | [diff] [blame] | 147 | GlobalValue *F = getNamedValue(Name); |
Craig Topper | ec0f0bc | 2014-04-09 06:08:46 +0000 | [diff] [blame] | 148 | if (!F) { |
Reid Spencer | ef9b9a7 | 2007-02-05 20:47:22 +0000 | [diff] [blame] | 149 | // Nope, add it |
Alexander Richardson | 47ff67b | 2018-08-23 09:25:17 +0000 | [diff] [blame] | 150 | Function *New = Function::Create(Ty, GlobalVariable::ExternalLinkage, |
| 151 | DL.getProgramAddressSpace(), Name); |
Nick Lewycky | 1186bf1 | 2009-01-04 22:54:40 +0000 | [diff] [blame] | 152 | if (!New->isIntrinsic()) // Intrinsics get attrs set on construction |
| 153 | New->setAttributes(AttributeList); |
Chris Lattner | 6056c49 | 2002-03-29 03:44:18 +0000 | [diff] [blame] | 154 | FunctionList.push_back(New); |
Chris Lattner | 70d1305 | 2007-01-07 08:09:25 +0000 | [diff] [blame] | 155 | return New; // Return the new prototype. |
Chris Lattner | 6056c49 | 2002-03-29 03:44:18 +0000 | [diff] [blame] | 156 | } |
Chris Lattner | 70d1305 | 2007-01-07 08:09:25 +0000 | [diff] [blame] | 157 | |
Chris Lattner | 70d1305 | 2007-01-07 08:09:25 +0000 | [diff] [blame] | 158 | // If the function exists but has the wrong type, return a bitcast to the |
| 159 | // right type. |
Alexander Richardson | 47ff67b | 2018-08-23 09:25:17 +0000 | [diff] [blame] | 160 | auto *PTy = PointerType::get(Ty, F->getAddressSpace()); |
| 161 | if (F->getType() != PTy) |
| 162 | return ConstantExpr::getBitCast(F, PTy); |
Bill Wendling | 85d043d | 2012-04-23 00:23:33 +0000 | [diff] [blame] | 163 | |
Chris Lattner | 70d1305 | 2007-01-07 08:09:25 +0000 | [diff] [blame] | 164 | // Otherwise, we just found the existing function or a prototype. |
Bill Wendling | 85d043d | 2012-04-23 00:23:33 +0000 | [diff] [blame] | 165 | return F; |
Chris Lattner | 6056c49 | 2002-03-29 03:44:18 +0000 | [diff] [blame] | 166 | } |
| 167 | |
Daniel Dunbar | 2928c83 | 2009-11-06 10:58:06 +0000 | [diff] [blame] | 168 | Constant *Module::getOrInsertFunction(StringRef Name, |
Chris Lattner | db125cf | 2011-07-18 04:54:35 +0000 | [diff] [blame] | 169 | FunctionType *Ty) { |
Reid Kleckner | 6707770 | 2017-03-21 16:57:19 +0000 | [diff] [blame] | 170 | return getOrInsertFunction(Name, Ty, AttributeList()); |
Nick Lewycky | 1186bf1 | 2009-01-04 22:54:40 +0000 | [diff] [blame] | 171 | } |
| 172 | |
Chris Lattner | 6056c49 | 2002-03-29 03:44:18 +0000 | [diff] [blame] | 173 | // getFunction - Look up the specified function in the module symbol table. |
| 174 | // If it does not exist, return null. |
| 175 | // |
Daniel Dunbar | 2928c83 | 2009-11-06 10:58:06 +0000 | [diff] [blame] | 176 | Function *Module::getFunction(StringRef Name) const { |
Daniel Dunbar | f56ec64 | 2009-03-06 22:04:43 +0000 | [diff] [blame] | 177 | return dyn_cast_or_null<Function>(getNamedValue(Name)); |
Chris Lattner | bb0e248 | 2008-06-27 21:09:10 +0000 | [diff] [blame] | 178 | } |
| 179 | |
Chris Lattner | 6083782 | 2003-12-31 08:43:01 +0000 | [diff] [blame] | 180 | //===----------------------------------------------------------------------===// |
| 181 | // Methods for easy access to the global variables in the module. |
| 182 | // |
| 183 | |
| 184 | /// getGlobalVariable - Look up the specified global variable in the module |
Chris Lattner | 3061467 | 2005-12-05 05:30:21 +0000 | [diff] [blame] | 185 | /// symbol table. If it does not exist, return null. The type argument |
| 186 | /// should be the underlying type of the global, i.e., it should not have |
| 187 | /// the top-level PointerType, which represents the address of the global. |
Rafael Espindola | bb46f52 | 2009-01-15 20:18:42 +0000 | [diff] [blame] | 188 | /// If AllowLocal is set to true, this function will return types that |
| 189 | /// have an local. By default, these types are not returned. |
Chris Lattner | 6083782 | 2003-12-31 08:43:01 +0000 | [diff] [blame] | 190 | /// |
Craig Topper | 306a7df | 2017-03-27 05:47:03 +0000 | [diff] [blame] | 191 | GlobalVariable *Module::getGlobalVariable(StringRef Name, |
| 192 | bool AllowLocal) const { |
Bill Wendling | 85d043d | 2012-04-23 00:23:33 +0000 | [diff] [blame] | 193 | if (GlobalVariable *Result = |
Daniel Dunbar | f56ec64 | 2009-03-06 22:04:43 +0000 | [diff] [blame] | 194 | dyn_cast_or_null<GlobalVariable>(getNamedValue(Name))) |
| 195 | if (AllowLocal || !Result->hasLocalLinkage()) |
Chris Lattner | 6083782 | 2003-12-31 08:43:01 +0000 | [diff] [blame] | 196 | return Result; |
Craig Topper | ec0f0bc | 2014-04-09 06:08:46 +0000 | [diff] [blame] | 197 | return nullptr; |
Chris Lattner | 6083782 | 2003-12-31 08:43:01 +0000 | [diff] [blame] | 198 | } |
| 199 | |
Bill Wendling | b4b130f | 2008-11-05 23:42:27 +0000 | [diff] [blame] | 200 | /// getOrInsertGlobal - Look up the specified global in the module symbol table. |
| 201 | /// 1. If it does not exist, add a declaration of the global and return it. |
| 202 | /// 2. Else, the global exists but has the wrong type: return the function |
| 203 | /// with a constantexpr cast to the right type. |
Matt Arsenault | f625c14 | 2013-09-28 01:08:00 +0000 | [diff] [blame] | 204 | /// 3. Finally, if the existing global is the correct declaration, return the |
Bill Wendling | b4b130f | 2008-11-05 23:42:27 +0000 | [diff] [blame] | 205 | /// existing global. |
Philip Pfaffe | 6016231 | 2019-01-02 15:41:47 +0000 | [diff] [blame] | 206 | Constant *Module::getOrInsertGlobal( |
| 207 | StringRef Name, Type *Ty, |
| 208 | function_ref<GlobalVariable *()> CreateGlobalCallback) { |
Bill Wendling | b7c2c12 | 2008-11-04 22:51:24 +0000 | [diff] [blame] | 209 | // See if we have a definition for the specified global already. |
Daniel Dunbar | f56ec64 | 2009-03-06 22:04:43 +0000 | [diff] [blame] | 210 | GlobalVariable *GV = dyn_cast_or_null<GlobalVariable>(getNamedValue(Name)); |
Philip Pfaffe | 6016231 | 2019-01-02 15:41:47 +0000 | [diff] [blame] | 211 | if (!GV) |
| 212 | GV = CreateGlobalCallback(); |
| 213 | assert(GV && "The CreateGlobalCallback is expected to create a global"); |
Bill Wendling | b7c2c12 | 2008-11-04 22:51:24 +0000 | [diff] [blame] | 214 | |
| 215 | // If the variable exists but has the wrong type, return a bitcast to the |
| 216 | // right type. |
Matt Arsenault | 2ebcd57 | 2013-09-30 21:23:03 +0000 | [diff] [blame] | 217 | Type *GVTy = GV->getType(); |
| 218 | PointerType *PTy = PointerType::get(Ty, GVTy->getPointerAddressSpace()); |
Matt Arsenault | b1d70af | 2013-09-30 23:31:50 +0000 | [diff] [blame] | 219 | if (GVTy != PTy) |
Matt Arsenault | 2ebcd57 | 2013-09-30 21:23:03 +0000 | [diff] [blame] | 220 | return ConstantExpr::getBitCast(GV, PTy); |
Bill Wendling | 85d043d | 2012-04-23 00:23:33 +0000 | [diff] [blame] | 221 | |
Bill Wendling | b7c2c12 | 2008-11-04 22:51:24 +0000 | [diff] [blame] | 222 | // Otherwise, we just found the existing function or a prototype. |
| 223 | return GV; |
| 224 | } |
| 225 | |
Philip Pfaffe | 6016231 | 2019-01-02 15:41:47 +0000 | [diff] [blame] | 226 | // Overload to construct a global variable using its constructor's defaults. |
| 227 | Constant *Module::getOrInsertGlobal(StringRef Name, Type *Ty) { |
| 228 | return getOrInsertGlobal(Name, Ty, [&] { |
| 229 | return new GlobalVariable(*this, Ty, false, GlobalVariable::ExternalLinkage, |
| 230 | nullptr, Name); |
| 231 | }); |
| 232 | } |
| 233 | |
Chris Lattner | 6083782 | 2003-12-31 08:43:01 +0000 | [diff] [blame] | 234 | //===----------------------------------------------------------------------===// |
Anton Korobeynikov | 8b0a8c8 | 2007-04-25 14:27:10 +0000 | [diff] [blame] | 235 | // Methods for easy access to the global variables in the module. |
| 236 | // |
| 237 | |
| 238 | // getNamedAlias - Look up the specified global in the module symbol table. |
| 239 | // If it does not exist, return null. |
| 240 | // |
Daniel Dunbar | 2928c83 | 2009-11-06 10:58:06 +0000 | [diff] [blame] | 241 | GlobalAlias *Module::getNamedAlias(StringRef Name) const { |
Daniel Dunbar | f56ec64 | 2009-03-06 22:04:43 +0000 | [diff] [blame] | 242 | return dyn_cast_or_null<GlobalAlias>(getNamedValue(Name)); |
Anton Korobeynikov | 8b0a8c8 | 2007-04-25 14:27:10 +0000 | [diff] [blame] | 243 | } |
| 244 | |
Dmitry Polukhin | ba49223 | 2016-04-07 12:32:19 +0000 | [diff] [blame] | 245 | GlobalIFunc *Module::getNamedIFunc(StringRef Name) const { |
| 246 | return dyn_cast_or_null<GlobalIFunc>(getNamedValue(Name)); |
| 247 | } |
| 248 | |
Devang Patel | 49fe6c9 | 2009-07-30 23:59:04 +0000 | [diff] [blame] | 249 | /// getNamedMetadata - Return the first NamedMDNode in the module with the |
Bill Wendling | 85d043d | 2012-04-23 00:23:33 +0000 | [diff] [blame] | 250 | /// specified name. This method returns null if a NamedMDNode with the |
Bob Wilson | 54eee52 | 2010-06-19 05:33:57 +0000 | [diff] [blame] | 251 | /// specified name is not found. |
Devang Patel | a762b09 | 2010-06-22 01:19:38 +0000 | [diff] [blame] | 252 | NamedMDNode *Module::getNamedMetadata(const Twine &Name) const { |
Devang Patel | 2f7d529 | 2010-06-16 00:53:55 +0000 | [diff] [blame] | 253 | SmallString<256> NameData; |
| 254 | StringRef NameRef = Name.toStringRef(NameData); |
Dan Gohman | 17aa92c | 2010-07-21 23:38:33 +0000 | [diff] [blame] | 255 | return static_cast<StringMap<NamedMDNode*> *>(NamedMDSymTab)->lookup(NameRef); |
Devang Patel | 2f7d529 | 2010-06-16 00:53:55 +0000 | [diff] [blame] | 256 | } |
| 257 | |
Bill Wendling | 85d043d | 2012-04-23 00:23:33 +0000 | [diff] [blame] | 258 | /// getOrInsertNamedMetadata - Return the first named MDNode in the module |
| 259 | /// with the specified name. This method returns a new NamedMDNode if a |
Devang Patel | 49fe6c9 | 2009-07-30 23:59:04 +0000 | [diff] [blame] | 260 | /// NamedMDNode with the specified name is not found. |
Daniel Dunbar | 2928c83 | 2009-11-06 10:58:06 +0000 | [diff] [blame] | 261 | NamedMDNode *Module::getOrInsertNamedMetadata(StringRef Name) { |
Dan Gohman | 17aa92c | 2010-07-21 23:38:33 +0000 | [diff] [blame] | 262 | NamedMDNode *&NMD = |
| 263 | (*static_cast<StringMap<NamedMDNode *> *>(NamedMDSymTab))[Name]; |
| 264 | if (!NMD) { |
| 265 | NMD = new NamedMDNode(Name); |
| 266 | NMD->setParent(this); |
| 267 | NamedMDList.push_back(NMD); |
| 268 | } |
Devang Patel | 49fe6c9 | 2009-07-30 23:59:04 +0000 | [diff] [blame] | 269 | return NMD; |
| 270 | } |
| 271 | |
Bill Wendling | d34cb1e | 2012-02-11 11:38:06 +0000 | [diff] [blame] | 272 | /// eraseNamedMetadata - Remove the given NamedMDNode from this module and |
| 273 | /// delete it. |
Dan Gohman | 17aa92c | 2010-07-21 23:38:33 +0000 | [diff] [blame] | 274 | void Module::eraseNamedMetadata(NamedMDNode *NMD) { |
| 275 | static_cast<StringMap<NamedMDNode *> *>(NamedMDSymTab)->erase(NMD->getName()); |
Duncan P. N. Exon Smith | eac3095 | 2015-10-08 23:49:46 +0000 | [diff] [blame] | 276 | NamedMDList.erase(NMD->getIterator()); |
Dan Gohman | 17aa92c | 2010-07-21 23:38:33 +0000 | [diff] [blame] | 277 | } |
| 278 | |
Duncan P. N. Exon Smith | dad20b2 | 2014-12-09 18:38:53 +0000 | [diff] [blame] | 279 | bool Module::isValidModFlagBehavior(Metadata *MD, ModFlagBehavior &MFB) { |
David Majnemer | f937622 | 2015-02-11 09:13:06 +0000 | [diff] [blame] | 280 | if (ConstantInt *Behavior = mdconst::dyn_extract_or_null<ConstantInt>(MD)) { |
Alexey Samsonov | e769dc3 | 2014-09-08 19:16:28 +0000 | [diff] [blame] | 281 | uint64_t Val = Behavior->getLimitedValue(); |
| 282 | if (Val >= ModFlagBehaviorFirstVal && Val <= ModFlagBehaviorLastVal) { |
| 283 | MFB = static_cast<ModFlagBehavior>(Val); |
| 284 | return true; |
| 285 | } |
| 286 | } |
| 287 | return false; |
| 288 | } |
| 289 | |
Bill Wendling | f20f281 | 2012-02-15 22:34:20 +0000 | [diff] [blame] | 290 | /// getModuleFlagsMetadata - Returns the module flags in the provided vector. |
| 291 | void Module:: |
| 292 | getModuleFlagsMetadata(SmallVectorImpl<ModuleFlagEntry> &Flags) const { |
| 293 | const NamedMDNode *ModFlags = getModuleFlagsMetadata(); |
| 294 | if (!ModFlags) return; |
| 295 | |
Duncan P. N. Exon Smith | 5bf8ade | 2014-11-11 21:30:22 +0000 | [diff] [blame] | 296 | for (const MDNode *Flag : ModFlags->operands()) { |
Alexey Samsonov | e769dc3 | 2014-09-08 19:16:28 +0000 | [diff] [blame] | 297 | ModFlagBehavior MFB; |
| 298 | if (Flag->getNumOperands() >= 3 && |
| 299 | isValidModFlagBehavior(Flag->getOperand(0), MFB) && |
David Majnemer | f937622 | 2015-02-11 09:13:06 +0000 | [diff] [blame] | 300 | dyn_cast_or_null<MDString>(Flag->getOperand(1))) { |
Manman Ren | 7d318bd | 2013-12-02 21:29:56 +0000 | [diff] [blame] | 301 | // Check the operands of the MDNode before accessing the operands. |
| 302 | // The verifier will actually catch these failures. |
Manman Ren | 7d318bd | 2013-12-02 21:29:56 +0000 | [diff] [blame] | 303 | MDString *Key = cast<MDString>(Flag->getOperand(1)); |
Duncan P. N. Exon Smith | dad20b2 | 2014-12-09 18:38:53 +0000 | [diff] [blame] | 304 | Metadata *Val = Flag->getOperand(2); |
Alexey Samsonov | e769dc3 | 2014-09-08 19:16:28 +0000 | [diff] [blame] | 305 | Flags.push_back(ModuleFlagEntry(MFB, Key, Val)); |
Manman Ren | 7d318bd | 2013-12-02 21:29:56 +0000 | [diff] [blame] | 306 | } |
Bill Wendling | f20f281 | 2012-02-15 22:34:20 +0000 | [diff] [blame] | 307 | } |
| 308 | } |
| 309 | |
Manman Ren | c8cfaa1 | 2013-07-16 23:21:16 +0000 | [diff] [blame] | 310 | /// Return the corresponding value if Key appears in module flags, otherwise |
| 311 | /// return null. |
Duncan P. N. Exon Smith | dad20b2 | 2014-12-09 18:38:53 +0000 | [diff] [blame] | 312 | Metadata *Module::getModuleFlag(StringRef Key) const { |
Manman Ren | c8cfaa1 | 2013-07-16 23:21:16 +0000 | [diff] [blame] | 313 | SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags; |
| 314 | getModuleFlagsMetadata(ModuleFlags); |
Benjamin Kramer | 6e9eeab | 2014-03-10 15:03:06 +0000 | [diff] [blame] | 315 | for (const ModuleFlagEntry &MFE : ModuleFlags) { |
Manman Ren | c8cfaa1 | 2013-07-16 23:21:16 +0000 | [diff] [blame] | 316 | if (Key == MFE.Key->getString()) |
| 317 | return MFE.Val; |
| 318 | } |
Craig Topper | ec0f0bc | 2014-04-09 06:08:46 +0000 | [diff] [blame] | 319 | return nullptr; |
Manman Ren | c8cfaa1 | 2013-07-16 23:21:16 +0000 | [diff] [blame] | 320 | } |
| 321 | |
Bill Wendling | d34cb1e | 2012-02-11 11:38:06 +0000 | [diff] [blame] | 322 | /// getModuleFlagsMetadata - Returns the NamedMDNode in the module that |
| 323 | /// represents module-level flags. This method returns null if there are no |
| 324 | /// module-level flags. |
| 325 | NamedMDNode *Module::getModuleFlagsMetadata() const { |
| 326 | return getNamedMetadata("llvm.module.flags"); |
| 327 | } |
| 328 | |
| 329 | /// getOrInsertModuleFlagsMetadata - Returns the NamedMDNode in the module that |
| 330 | /// represents module-level flags. If module-level flags aren't found, it |
| 331 | /// creates the named metadata that contains them. |
| 332 | NamedMDNode *Module::getOrInsertModuleFlagsMetadata() { |
| 333 | return getOrInsertNamedMetadata("llvm.module.flags"); |
| 334 | } |
| 335 | |
| 336 | /// addModuleFlag - Add a module-level flag to the module-level flags |
| 337 | /// metadata. It will create the module-level flags named metadata if it doesn't |
| 338 | /// already exist. |
Bill Wendling | e6bd7a8 | 2012-02-16 10:28:10 +0000 | [diff] [blame] | 339 | void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key, |
Duncan P. N. Exon Smith | dad20b2 | 2014-12-09 18:38:53 +0000 | [diff] [blame] | 340 | Metadata *Val) { |
Bill Wendling | d34cb1e | 2012-02-11 11:38:06 +0000 | [diff] [blame] | 341 | Type *Int32Ty = Type::getInt32Ty(Context); |
Duncan P. N. Exon Smith | dad20b2 | 2014-12-09 18:38:53 +0000 | [diff] [blame] | 342 | Metadata *Ops[3] = { |
| 343 | ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Behavior)), |
| 344 | MDString::get(Context, Key), Val}; |
Bill Wendling | d34cb1e | 2012-02-11 11:38:06 +0000 | [diff] [blame] | 345 | getOrInsertModuleFlagsMetadata()->addOperand(MDNode::get(Context, Ops)); |
| 346 | } |
Bill Wendling | e6bd7a8 | 2012-02-16 10:28:10 +0000 | [diff] [blame] | 347 | void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key, |
Duncan P. N. Exon Smith | dad20b2 | 2014-12-09 18:38:53 +0000 | [diff] [blame] | 348 | Constant *Val) { |
| 349 | addModuleFlag(Behavior, Key, ConstantAsMetadata::get(Val)); |
| 350 | } |
| 351 | void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key, |
Bill Wendling | d34cb1e | 2012-02-11 11:38:06 +0000 | [diff] [blame] | 352 | uint32_t Val) { |
| 353 | Type *Int32Ty = Type::getInt32Ty(Context); |
| 354 | addModuleFlag(Behavior, Key, ConstantInt::get(Int32Ty, Val)); |
| 355 | } |
| 356 | void Module::addModuleFlag(MDNode *Node) { |
| 357 | assert(Node->getNumOperands() == 3 && |
| 358 | "Invalid number of operands for module flag!"); |
Duncan P. N. Exon Smith | dad20b2 | 2014-12-09 18:38:53 +0000 | [diff] [blame] | 359 | assert(mdconst::hasa<ConstantInt>(Node->getOperand(0)) && |
Bill Wendling | d34cb1e | 2012-02-11 11:38:06 +0000 | [diff] [blame] | 360 | isa<MDString>(Node->getOperand(1)) && |
| 361 | "Invalid operand types for module flag!"); |
| 362 | getOrInsertModuleFlagsMetadata()->addOperand(Node); |
| 363 | } |
Chris Lattner | f33fa6f | 2002-04-13 18:58:33 +0000 | [diff] [blame] | 364 | |
Rafael Espindola | aab87fe | 2014-02-25 20:01:08 +0000 | [diff] [blame] | 365 | void Module::setDataLayout(StringRef Desc) { |
Rafael Espindola | 3f0a9af | 2014-02-25 22:23:04 +0000 | [diff] [blame] | 366 | DL.reset(Desc); |
Rafael Espindola | aab87fe | 2014-02-25 20:01:08 +0000 | [diff] [blame] | 367 | } |
| 368 | |
Mehdi Amini | c94da20 | 2015-03-04 18:43:29 +0000 | [diff] [blame] | 369 | void Module::setDataLayout(const DataLayout &Other) { DL = Other; } |
Rafael Espindola | aab87fe | 2014-02-25 20:01:08 +0000 | [diff] [blame] | 370 | |
Mehdi Amini | c94da20 | 2015-03-04 18:43:29 +0000 | [diff] [blame] | 371 | const DataLayout &Module::getDataLayout() const { return DL; } |
Rafael Espindola | aab87fe | 2014-02-25 20:01:08 +0000 | [diff] [blame] | 372 | |
Adrian Prantl | 48bb8b4 | 2016-04-08 22:43:03 +0000 | [diff] [blame] | 373 | DICompileUnit *Module::debug_compile_units_iterator::operator*() const { |
| 374 | return cast<DICompileUnit>(CUs->getOperand(Idx)); |
| 375 | } |
| 376 | DICompileUnit *Module::debug_compile_units_iterator::operator->() const { |
| 377 | return cast<DICompileUnit>(CUs->getOperand(Idx)); |
| 378 | } |
| 379 | |
| 380 | void Module::debug_compile_units_iterator::SkipNoDebugCUs() { |
| 381 | while (CUs && (Idx < CUs->getNumOperands()) && |
| 382 | ((*this)->getEmissionKind() == DICompileUnit::NoDebug)) |
| 383 | ++Idx; |
| 384 | } |
| 385 | |
Chris Lattner | 6083782 | 2003-12-31 08:43:01 +0000 | [diff] [blame] | 386 | //===----------------------------------------------------------------------===// |
Jeffrey Yasskin | f0356fe | 2010-01-27 20:34:15 +0000 | [diff] [blame] | 387 | // Methods to control the materialization of GlobalValues in the Module. |
| 388 | // |
| 389 | void Module::setMaterializer(GVMaterializer *GVM) { |
| 390 | assert(!Materializer && |
Rafael Espindola | 838f8a4 | 2015-12-18 20:13:39 +0000 | [diff] [blame] | 391 | "Module already has a GVMaterializer. Call materializeAll" |
Jeffrey Yasskin | f0356fe | 2010-01-27 20:34:15 +0000 | [diff] [blame] | 392 | " to clear it out before setting another one."); |
| 393 | Materializer.reset(GVM); |
| 394 | } |
| 395 | |
Peter Collingbourne | 76c218e | 2016-11-09 17:49:19 +0000 | [diff] [blame] | 396 | Error Module::materialize(GlobalValue *GV) { |
Rafael Espindola | af9e8e6 | 2013-11-05 19:36:34 +0000 | [diff] [blame] | 397 | if (!Materializer) |
Peter Collingbourne | 76c218e | 2016-11-09 17:49:19 +0000 | [diff] [blame] | 398 | return Error::success(); |
Rafael Espindola | af9e8e6 | 2013-11-05 19:36:34 +0000 | [diff] [blame] | 399 | |
Rafael Espindola | c498284 | 2014-10-24 22:50:48 +0000 | [diff] [blame] | 400 | return Materializer->materialize(GV); |
Jeffrey Yasskin | f0356fe | 2010-01-27 20:34:15 +0000 | [diff] [blame] | 401 | } |
| 402 | |
Peter Collingbourne | 76c218e | 2016-11-09 17:49:19 +0000 | [diff] [blame] | 403 | Error Module::materializeAll() { |
Jeffrey Yasskin | f0356fe | 2010-01-27 20:34:15 +0000 | [diff] [blame] | 404 | if (!Materializer) |
Peter Collingbourne | 76c218e | 2016-11-09 17:49:19 +0000 | [diff] [blame] | 405 | return Error::success(); |
Rafael Espindola | 17920c2 | 2016-01-15 19:00:20 +0000 | [diff] [blame] | 406 | std::unique_ptr<GVMaterializer> M = std::move(Materializer); |
| 407 | return M->materializeModule(); |
Jeffrey Yasskin | f0356fe | 2010-01-27 20:34:15 +0000 | [diff] [blame] | 408 | } |
| 409 | |
Peter Collingbourne | 76c218e | 2016-11-09 17:49:19 +0000 | [diff] [blame] | 410 | Error Module::materializeMetadata() { |
Rafael Espindola | dc6141a | 2015-03-13 21:54:20 +0000 | [diff] [blame] | 411 | if (!Materializer) |
Peter Collingbourne | 76c218e | 2016-11-09 17:49:19 +0000 | [diff] [blame] | 412 | return Error::success(); |
Rafael Espindola | dc6141a | 2015-03-13 21:54:20 +0000 | [diff] [blame] | 413 | return Materializer->materializeMetadata(); |
| 414 | } |
| 415 | |
Jeffrey Yasskin | f0356fe | 2010-01-27 20:34:15 +0000 | [diff] [blame] | 416 | //===----------------------------------------------------------------------===// |
Chris Lattner | 6083782 | 2003-12-31 08:43:01 +0000 | [diff] [blame] | 417 | // Other module related stuff. |
| 418 | // |
| 419 | |
Rafael Espindola | eee41db | 2014-12-03 07:18:23 +0000 | [diff] [blame] | 420 | std::vector<StructType *> Module::getIdentifiedStructTypes() const { |
| 421 | // If we have a materializer, it is possible that some unread function |
| 422 | // uses a type that is currently not visible to a TypeFinder, so ask |
| 423 | // the materializer which types it created. |
| 424 | if (Materializer) |
| 425 | return Materializer->getIdentifiedStructTypes(); |
| 426 | |
| 427 | std::vector<StructType *> Ret; |
| 428 | TypeFinder SrcStructTypes; |
| 429 | SrcStructTypes.run(*this, true); |
| 430 | Ret.assign(SrcStructTypes.begin(), SrcStructTypes.end()); |
| 431 | return Ret; |
| 432 | } |
Chris Lattner | 6083782 | 2003-12-31 08:43:01 +0000 | [diff] [blame] | 433 | |
Eric Christopher | cf84d86 | 2012-04-16 23:54:31 +0000 | [diff] [blame] | 434 | // dropAllReferences() - This function causes all the subelements to "let go" |
Chris Lattner | 9da0715 | 2002-08-17 23:32:47 +0000 | [diff] [blame] | 435 | // of all references that they are maintaining. This allows one to 'delete' a |
| 436 | // whole module at a time, even though there may be circular references... first |
| 437 | // all references are dropped, and all use counts go to zero. Then everything |
Misha Brukman | 6b63452 | 2003-10-10 17:54:14 +0000 | [diff] [blame] | 438 | // is deleted for real. Note that no operations are valid on an object that |
Chris Lattner | 9da0715 | 2002-08-17 23:32:47 +0000 | [diff] [blame] | 439 | // has "dropped all references", except operator delete. |
Chris Lattner | 0095054 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 440 | // |
| 441 | void Module::dropAllReferences() { |
David Majnemer | 8234268 | 2014-07-03 16:12:55 +0000 | [diff] [blame] | 442 | for (Function &F : *this) |
| 443 | F.dropAllReferences(); |
Chris Lattner | dd6dfbc | 2001-10-13 06:58:40 +0000 | [diff] [blame] | 444 | |
David Majnemer | 8234268 | 2014-07-03 16:12:55 +0000 | [diff] [blame] | 445 | for (GlobalVariable &GV : globals()) |
| 446 | GV.dropAllReferences(); |
Anton Korobeynikov | a80e118 | 2007-04-28 13:45:00 +0000 | [diff] [blame] | 447 | |
David Majnemer | 8234268 | 2014-07-03 16:12:55 +0000 | [diff] [blame] | 448 | for (GlobalAlias &GA : aliases()) |
| 449 | GA.dropAllReferences(); |
Dmitry Polukhin | ba49223 | 2016-04-07 12:32:19 +0000 | [diff] [blame] | 450 | |
| 451 | for (GlobalIFunc &GIF : ifuncs()) |
| 452 | GIF.dropAllReferences(); |
Chris Lattner | 0095054 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 453 | } |
Diego Novillo | 0a0d620 | 2014-04-17 22:33:50 +0000 | [diff] [blame] | 454 | |
Nirav Dave | 11fdc78 | 2017-03-18 00:44:07 +0000 | [diff] [blame] | 455 | unsigned Module::getNumberRegisterParameters() const { |
| 456 | auto *Val = |
| 457 | cast_or_null<ConstantAsMetadata>(getModuleFlag("NumRegisterParameters")); |
| 458 | if (!Val) |
| 459 | return 0; |
| 460 | return cast<ConstantInt>(Val->getValue())->getZExtValue(); |
| 461 | } |
| 462 | |
Diego Novillo | 0a0d620 | 2014-04-17 22:33:50 +0000 | [diff] [blame] | 463 | unsigned Module::getDwarfVersion() const { |
Duncan P. N. Exon Smith | dad20b2 | 2014-12-09 18:38:53 +0000 | [diff] [blame] | 464 | auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("Dwarf Version")); |
Diego Novillo | 0a0d620 | 2014-04-17 22:33:50 +0000 | [diff] [blame] | 465 | if (!Val) |
Reid Kleckner | defbd1f | 2015-08-05 22:26:20 +0000 | [diff] [blame] | 466 | return 0; |
| 467 | return cast<ConstantInt>(Val->getValue())->getZExtValue(); |
| 468 | } |
| 469 | |
| 470 | unsigned Module::getCodeViewFlag() const { |
| 471 | auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("CodeView")); |
| 472 | if (!Val) |
| 473 | return 0; |
Duncan P. N. Exon Smith | dad20b2 | 2014-12-09 18:38:53 +0000 | [diff] [blame] | 474 | return cast<ConstantInt>(Val->getValue())->getZExtValue(); |
Diego Novillo | 0a0d620 | 2014-04-17 22:33:50 +0000 | [diff] [blame] | 475 | } |
David Majnemer | c8a1169 | 2014-06-27 18:19:56 +0000 | [diff] [blame] | 476 | |
Jessica Paquette | 849da55 | 2018-05-18 17:26:39 +0000 | [diff] [blame] | 477 | unsigned Module::getInstructionCount() { |
| 478 | unsigned NumInstrs = 0; |
| 479 | for (Function &F : FunctionList) |
| 480 | NumInstrs += F.getInstructionCount(); |
| 481 | return NumInstrs; |
| 482 | } |
| 483 | |
David Majnemer | c8a1169 | 2014-06-27 18:19:56 +0000 | [diff] [blame] | 484 | Comdat *Module::getOrInsertComdat(StringRef Name) { |
David Blaikie | 1d4f28c | 2014-11-19 05:49:42 +0000 | [diff] [blame] | 485 | auto &Entry = *ComdatSymTab.insert(std::make_pair(Name, Comdat())).first; |
David Majnemer | c8a1169 | 2014-06-27 18:19:56 +0000 | [diff] [blame] | 486 | Entry.second.Name = &Entry; |
| 487 | return &Entry.second; |
| 488 | } |
Justin Hibbits | 893f22f | 2014-11-07 04:46:10 +0000 | [diff] [blame] | 489 | |
| 490 | PICLevel::Level Module::getPICLevel() const { |
Duncan P. N. Exon Smith | dad20b2 | 2014-12-09 18:38:53 +0000 | [diff] [blame] | 491 | auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("PIC Level")); |
Justin Hibbits | 893f22f | 2014-11-07 04:46:10 +0000 | [diff] [blame] | 492 | |
Hans Wennborg | 4d651e4 | 2015-10-06 23:24:35 +0000 | [diff] [blame] | 493 | if (!Val) |
Davide Italiano | d2e7196 | 2016-06-17 18:07:14 +0000 | [diff] [blame] | 494 | return PICLevel::NotPIC; |
Justin Hibbits | 893f22f | 2014-11-07 04:46:10 +0000 | [diff] [blame] | 495 | |
Duncan P. N. Exon Smith | dad20b2 | 2014-12-09 18:38:53 +0000 | [diff] [blame] | 496 | return static_cast<PICLevel::Level>( |
| 497 | cast<ConstantInt>(Val->getValue())->getZExtValue()); |
Justin Hibbits | 893f22f | 2014-11-07 04:46:10 +0000 | [diff] [blame] | 498 | } |
| 499 | |
| 500 | void Module::setPICLevel(PICLevel::Level PL) { |
Teresa Johnson | 1fd5bb9 | 2017-05-23 00:08:00 +0000 | [diff] [blame] | 501 | addModuleFlag(ModFlagBehavior::Max, "PIC Level", PL); |
Justin Hibbits | 893f22f | 2014-11-07 04:46:10 +0000 | [diff] [blame] | 502 | } |
Easwaran Raman | 52c4f7d | 2015-12-03 20:57:37 +0000 | [diff] [blame] | 503 | |
Sriraman Tallam | d41672f | 2016-04-28 18:15:44 +0000 | [diff] [blame] | 504 | PIELevel::Level Module::getPIELevel() const { |
| 505 | auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("PIE Level")); |
| 506 | |
| 507 | if (!Val) |
| 508 | return PIELevel::Default; |
| 509 | |
| 510 | return static_cast<PIELevel::Level>( |
| 511 | cast<ConstantInt>(Val->getValue())->getZExtValue()); |
| 512 | } |
| 513 | |
| 514 | void Module::setPIELevel(PIELevel::Level PL) { |
Teresa Johnson | 1fd5bb9 | 2017-05-23 00:08:00 +0000 | [diff] [blame] | 515 | addModuleFlag(ModFlagBehavior::Max, "PIE Level", PL); |
Sriraman Tallam | d41672f | 2016-04-28 18:15:44 +0000 | [diff] [blame] | 516 | } |
| 517 | |
Caroline Tice | a53c520 | 2018-09-21 18:41:31 +0000 | [diff] [blame] | 518 | Optional<CodeModel::Model> Module::getCodeModel() const { |
| 519 | auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("Code Model")); |
| 520 | |
| 521 | if (!Val) |
| 522 | return None; |
| 523 | |
| 524 | return static_cast<CodeModel::Model>( |
| 525 | cast<ConstantInt>(Val->getValue())->getZExtValue()); |
| 526 | } |
| 527 | |
| 528 | void Module::setCodeModel(CodeModel::Model CL) { |
| 529 | // Linking object files with different code models is undefined behavior |
| 530 | // because the compiler would have to generate additional code (to span |
| 531 | // longer jumps) if a larger code model is used with a smaller one. |
| 532 | // Therefore we will treat attempts to mix code models as an error. |
| 533 | addModuleFlag(ModFlagBehavior::Error, "Code Model", CL); |
| 534 | } |
| 535 | |
Easwaran Raman | af640bf | 2016-03-18 21:29:30 +0000 | [diff] [blame] | 536 | void Module::setProfileSummary(Metadata *M) { |
| 537 | addModuleFlag(ModFlagBehavior::Error, "ProfileSummary", M); |
| 538 | } |
| 539 | |
| 540 | Metadata *Module::getProfileSummary() { |
| 541 | return getModuleFlag("ProfileSummary"); |
| 542 | } |
Teresa Johnson | 89c5c63 | 2016-04-20 14:39:45 +0000 | [diff] [blame] | 543 | |
Peter Collingbourne | 5498e18 | 2016-11-08 06:03:43 +0000 | [diff] [blame] | 544 | void Module::setOwnedMemoryBuffer(std::unique_ptr<MemoryBuffer> MB) { |
| 545 | OwnedMemoryBuffer = std::move(MB); |
| 546 | } |
| 547 | |
Sriraman Tallam | 11fc5bb | 2018-02-23 21:32:06 +0000 | [diff] [blame] | 548 | bool Module::getRtLibUseGOT() const { |
| 549 | auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("RtLibUseGOT")); |
| 550 | return Val && (cast<ConstantInt>(Val->getValue())->getZExtValue() > 0); |
| 551 | } |
| 552 | |
| 553 | void Module::setRtLibUseGOT() { |
| 554 | addModuleFlag(ModFlagBehavior::Max, "RtLibUseGOT", 1); |
| 555 | } |
| 556 | |
Alex Lorenz | 6592c09 | 2018-12-14 01:14:10 +0000 | [diff] [blame] | 557 | void Module::setSDKVersion(const VersionTuple &V) { |
| 558 | SmallVector<unsigned, 3> Entries; |
| 559 | Entries.push_back(V.getMajor()); |
| 560 | if (auto Minor = V.getMinor()) { |
| 561 | Entries.push_back(*Minor); |
| 562 | if (auto Subminor = V.getSubminor()) |
| 563 | Entries.push_back(*Subminor); |
| 564 | // Ignore the 'build' component as it can't be represented in the object |
| 565 | // file. |
| 566 | } |
| 567 | addModuleFlag(ModFlagBehavior::Warning, "SDK Version", |
| 568 | ConstantDataArray::get(Context, Entries)); |
| 569 | } |
| 570 | |
| 571 | VersionTuple Module::getSDKVersion() const { |
| 572 | auto *CM = dyn_cast_or_null<ConstantAsMetadata>(getModuleFlag("SDK Version")); |
| 573 | if (!CM) |
| 574 | return {}; |
| 575 | auto *Arr = dyn_cast_or_null<ConstantDataArray>(CM->getValue()); |
| 576 | if (!Arr) |
| 577 | return {}; |
| 578 | auto getVersionComponent = [&](unsigned Index) -> Optional<unsigned> { |
| 579 | if (Index >= Arr->getNumElements()) |
| 580 | return None; |
| 581 | return (unsigned)Arr->getElementAsInteger(Index); |
| 582 | }; |
| 583 | auto Major = getVersionComponent(0); |
| 584 | if (!Major) |
| 585 | return {}; |
| 586 | VersionTuple Result = VersionTuple(*Major); |
| 587 | if (auto Minor = getVersionComponent(1)) { |
| 588 | Result = VersionTuple(*Major, *Minor); |
| 589 | if (auto Subminor = getVersionComponent(2)) { |
| 590 | Result = VersionTuple(*Major, *Minor, *Subminor); |
| 591 | } |
| 592 | } |
| 593 | return Result; |
| 594 | } |
| 595 | |
Teresa Johnson | 89c5c63 | 2016-04-20 14:39:45 +0000 | [diff] [blame] | 596 | GlobalVariable *llvm::collectUsedGlobalVariables( |
| 597 | const Module &M, SmallPtrSetImpl<GlobalValue *> &Set, bool CompilerUsed) { |
| 598 | const char *Name = CompilerUsed ? "llvm.compiler.used" : "llvm.used"; |
| 599 | GlobalVariable *GV = M.getGlobalVariable(Name); |
| 600 | if (!GV || !GV->hasInitializer()) |
| 601 | return GV; |
| 602 | |
| 603 | const ConstantArray *Init = cast<ConstantArray>(GV->getInitializer()); |
| 604 | for (Value *Op : Init->operands()) { |
| 605 | GlobalValue *G = cast<GlobalValue>(Op->stripPointerCastsNoFollowAliases()); |
| 606 | Set.insert(G); |
| 607 | } |
| 608 | return GV; |
| 609 | } |