80 #include <system_error> 85 using namespace lowertypetests;
87 #define DEBUG_TYPE "lowertypetests" 89 STATISTIC(ByteArraySizeBits,
"Byte array size in bits");
90 STATISTIC(ByteArraySizeBytes,
"Byte array size in bytes");
91 STATISTIC(NumByteArraysCreated,
"Number of byte arrays created");
92 STATISTIC(NumTypeTestCallsLowered,
"Number of type test calls lowered");
93 STATISTIC(NumTypeIdDisjointSets,
"Number of disjoint sets of type identifiers");
96 "lowertypetests-avoid-reuse",
97 cl::desc(
"Try to avoid reuse of byte array addresses using aliases"),
101 "lowertypetests-summary-action",
102 cl::desc(
"What to do with the summary when running this pass"),
105 "Import typeid resolutions from summary and globals"),
107 "Export typeid resolutions to summary and globals")),
111 "lowertypetests-read-summary",
112 cl::desc(
"Read summary from given YAML file before running pass"),
116 "lowertypetests-write-summary",
117 cl::desc(
"Write summary to given YAML file after running pass"),
131 return Bits.count(BitOffset);
144 for (uint64_t
B :
Bits)
174 for (uint64_t
Offset : Offsets) {
184 Fragments.emplace_back();
185 std::vector<uint64_t> &Fragment = Fragments.back();
186 uint64_t FragmentIndex = Fragments.size() - 1;
188 for (
auto ObjIndex : F) {
189 uint64_t OldFragmentIndex = FragmentMap[ObjIndex];
190 if (OldFragmentIndex == 0) {
193 Fragment.push_back(ObjIndex);
200 std::vector<uint64_t> &OldFragment = Fragments[OldFragmentIndex];
201 Fragment.insert(Fragment.end(), OldFragment.begin(), OldFragment.end());
207 for (uint64_t ObjIndex : Fragment)
208 FragmentMap[ObjIndex] = FragmentIndex;
212 uint64_t
BitSize, uint64_t &AllocByteOffset,
213 uint8_t &AllocMask) {
216 for (
unsigned I = 1;
I != BitsPerByte; ++
I)
217 if (BitAllocs[
I] < BitAllocs[Bit])
220 AllocByteOffset = BitAllocs[
Bit];
223 unsigned ReqSize = AllocByteOffset +
BitSize;
224 BitAllocs[
Bit] = ReqSize;
225 if (Bytes.size() < ReqSize)
226 Bytes.resize(ReqSize);
229 AllocMask = 1 <<
Bit;
230 for (uint64_t
B : Bits)
231 Bytes[AllocByteOffset +
B] |= AllocMask;
236 struct ByteArrayInfo {
237 std::set<uint64_t>
Bits;
241 uint8_t *MaskPtr =
nullptr;
249 class GlobalTypeMember final :
TrailingObjects<GlobalTypeMember, MDNode *> {
263 size_t numTrailingObjects(OverloadToken<MDNode *>)
const {
return NTypes; }
267 bool IsDefinition,
bool IsExported,
269 auto *GTM =
static_cast<GlobalTypeMember *
>(Alloc.
Allocate(
270 totalSizeToAlloc<MDNode *>(Types.
size()),
alignof(GlobalTypeMember)));
272 GTM->NTypes = Types.
size();
273 GTM->IsDefinition = IsDefinition;
274 GTM->IsExported = IsExported;
275 std::uninitialized_copy(Types.
begin(), Types.
end(),
276 GTM->getTrailingObjects<
MDNode *>());
284 bool isDefinition()
const {
288 bool isExported()
const {
293 return makeArrayRef(getTrailingObjects<MDNode *>(), NTypes);
297 struct ICallBranchFunnel final
302 auto *Call =
static_cast<ICallBranchFunnel *
>(
303 Alloc.
Allocate(totalSizeToAlloc<GlobalTypeMember *>(Targets.
size()),
304 alignof(ICallBranchFunnel)));
306 Call->UniqueId = UniqueId;
307 Call->NTargets = Targets.
size();
308 std::uninitialized_copy(Targets.
begin(), Targets.
end(),
309 Call->getTrailingObjects<GlobalTypeMember *>());
315 return makeArrayRef(getTrailingObjects<GlobalTypeMember *>(), NTargets);
324 class LowerTypeTestsModule {
344 uint64_t IndirectIndex = 1;
349 struct TypeIdUserInfo {
350 std::vector<CallInst *> CallSites;
351 bool IsExported =
false;
359 struct TypeIdLowering {
383 std::vector<ByteArrayInfo> ByteArrayInfos;
385 Function *WeakInitializerFn =
nullptr;
387 bool shouldExportConstantsAsAbsoluteSymbols();
388 uint8_t *exportTypeId(
StringRef TypeId,
const TypeIdLowering &TIL);
389 TypeIdLowering importTypeId(
StringRef TypeId);
391 void importFunction(
Function *
F,
bool isDefinition);
396 ByteArrayInfo *createByteArray(
BitSetInfo &BSI);
397 void allocateByteArrays();
400 void lowerTypeTestCalls(
404 const TypeIdLowering &TIL);
408 unsigned getJumpTableEntrySize();
409 Type *getJumpTableEntryType();
425 void replaceWeakDeclarationWithJumpTablePtr(
Function *F,
Constant *
JT,
bool IsDefinition);
427 void findGlobalVariableUsersOf(
Constant *
C,
437 void replaceCfiUses(
Function *Old,
Value *New,
bool IsDefinition);
441 void replaceDirectCalls(
Value *Old,
Value *New);
451 static bool runForTesting(
Module &M);
457 bool UseCommandLine =
false;
462 LowerTypeTests() :
ModulePass(ID), UseCommandLine(
true) {
468 :
ModulePass(ID), ExportSummary(ExportSummary),
469 ImportSummary(ImportSummary) {
473 bool runOnModule(
Module &M)
override {
475 return LowerTypeTestsModule::runForTesting(M);
476 return LowerTypeTestsModule(M, ExportSummary, ImportSummary).lower();
490 return new LowerTypeTests(ExportSummary, ImportSummary);
502 for (
auto &GlobalAndOffset : GlobalLayout) {
503 for (
MDNode *
Type : GlobalAndOffset.first->types()) {
504 if (
Type->getOperand(1) != TypeId)
508 cast<ConstantAsMetadata>(
Type->getOperand(0))->getValue())
510 BSB.
addOffset(GlobalAndOffset.second + Offset);
521 auto BitsType = cast<IntegerType>(Bits->
getType());
522 unsigned BitWidth = BitsType->getBitWidth();
532 ByteArrayInfo *LowerTypeTestsModule::createByteArray(
BitSetInfo &BSI) {
541 ByteArrayInfos.emplace_back();
542 ByteArrayInfo *BAI = &ByteArrayInfos.back();
544 BAI->Bits = BSI.
Bits;
546 BAI->ByteArray = ByteArrayGlobal;
547 BAI->MaskGlobal = MaskGlobal;
551 void LowerTypeTestsModule::allocateByteArrays() {
552 std::stable_sort(ByteArrayInfos.begin(), ByteArrayInfos.end(),
553 [](
const ByteArrayInfo &BAI1,
const ByteArrayInfo &BAI2) {
554 return BAI1.BitSize > BAI2.BitSize;
557 std::vector<uint64_t> ByteArrayOffsets(ByteArrayInfos.size());
560 for (
unsigned I = 0;
I != ByteArrayInfos.size(); ++
I) {
561 ByteArrayInfo *BAI = &ByteArrayInfos[
I];
564 BAB.allocate(BAI->Bits, BAI->BitSize, ByteArrayOffsets[
I], Mask);
566 BAI->MaskGlobal->replaceAllUsesWith(
568 BAI->MaskGlobal->eraseFromParent();
570 *BAI->MaskPtr =
Mask;
578 for (
unsigned I = 0;
I != ByteArrayInfos.size(); ++
I) {
579 ByteArrayInfo *BAI = &ByteArrayInfos[
I];
584 ByteArrayConst->
getType(), ByteArray, Idxs);
591 BAI->ByteArray->replaceAllUsesWith(Alias);
592 BAI->ByteArray->eraseFromParent();
595 ByteArraySizeBits = BAB.BitAllocs[0] + BAB.BitAllocs[1] + BAB.BitAllocs[2] +
596 BAB.BitAllocs[3] + BAB.BitAllocs[4] + BAB.BitAllocs[5] +
597 BAB.BitAllocs[6] + BAB.BitAllocs[7];
598 ByteArraySizeBytes = BAB.Bytes.size();
604 const TypeIdLowering &TIL,
611 Constant *ByteArray = TIL.TheByteArray;
618 "bits_use", ByteArray, &M);
631 Value *V, uint64_t COffset) {
632 if (
auto GV = dyn_cast<GlobalObject>(V)) {
636 if (
Type->getOperand(1) != TypeId)
640 cast<ConstantAsMetadata>(
Type->getOperand(0))->getValue())
642 if (COffset == Offset)
648 if (
auto GEP = dyn_cast<GEPOperator>(V)) {
650 bool Result =
GEP->accumulateConstantOffset(DL, APOffset);
653 COffset += APOffset.getZExtValue();
657 if (
auto Op = dyn_cast<Operator>(V)) {
658 if (
Op->getOpcode() == Instruction::BitCast)
672 const TypeIdLowering &TIL) {
716 return OffsetInRange;
723 if (
auto *Br = dyn_cast<BranchInst>(*CI->
user_begin()))
733 for (
auto &Phi : Else->
phis())
734 Phi.addIncoming(Phi.getIncomingValueForBlock(Then), InitialBB);
737 return createBitSetTest(ThenB, TIL, BitOffset);
744 Value *
Bit = createBitSetTest(ThenB, TIL, BitOffset);
758 void LowerTypeTestsModule::buildBitSetsFromGlobalVariables(
764 std::vector<Constant *> GlobalInits;
766 for (GlobalTypeMember *
G : Globals) {
772 uint64_t Padding =
NextPowerOf2(InitSize - 1) - InitSize;
779 Padding =
alignTo(InitSize, 32) - InitSize;
781 GlobalInits.push_back(
784 if (!GlobalInits.empty())
785 GlobalInits.pop_back();
787 auto *CombinedGlobal =
796 for (
unsigned I = 0;
I != Globals.size(); ++
I)
798 GlobalLayout[Globals[
I]] = CombinedGlobalLayout->getElementOffset(
I * 2);
800 lowerTypeTestCalls(TypeIds, CombinedGlobal, GlobalLayout);
805 for (
unsigned I = 0;
I != Globals.size(); ++
I) {
812 NewInit->
getType(), CombinedGlobal, CombinedGlobalIdxs);
816 "", CombinedGlobalElemPtr, &M);
818 GAlias->takeName(GV);
824 bool LowerTypeTestsModule::shouldExportConstantsAsAbsoluteSymbols() {
837 uint8_t *LowerTypeTestsModule::exportTypeId(
StringRef TypeId,
838 const TypeIdLowering &TIL) {
840 ExportSummary->getOrInsertTypeIdSummary(TypeId).TTRes;
846 "__typeid_" + TypeId +
"_" + Name,
C, &M);
851 if (shouldExportConstantsAsAbsoluteSymbols())
854 Storage = cast<ConstantInt>(
C)->getZExtValue();
858 ExportGlobal(
"global_addr", TIL.OffsetedGlobal);
863 ExportConstant(
"align", TTRes.
AlignLog2, TIL.AlignLog2);
864 ExportConstant(
"size_m1", TTRes.
SizeM1, TIL.SizeM1);
866 uint64_t
BitSize = cast<ConstantInt>(TIL.SizeM1)->getZExtValue() + 1;
874 ExportGlobal(
"byte_array", TIL.TheByteArray);
875 if (shouldExportConstantsAsAbsoluteSymbols())
876 ExportGlobal(
"bit_mask", TIL.BitMask);
882 ExportConstant(
"inline_bits", TTRes.
InlineBits, TIL.InlineBits);
887 LowerTypeTestsModule::TypeIdLowering
888 LowerTypeTestsModule::importTypeId(
StringRef TypeId) {
889 const TypeIdSummary *TidSummary = ImportSummary->getTypeIdSummary(TypeId);
900 Constant *
C = M.getOrInsertGlobal((
"__typeid_" + TypeId +
"_" +
Name).str(),
902 if (
auto *GV = dyn_cast<GlobalVariable>(C))
908 auto ImportConstant = [&](
StringRef Name, uint64_t Const,
unsigned AbsWidth,
910 if (!shouldExportConstantsAsAbsoluteSymbols()) {
913 if (!isa<IntegerType>(Ty))
920 if (isa<IntegerType>(Ty))
925 auto SetAbsRange = [&](uint64_t Min, uint64_t Max) {
931 if (AbsWidth == IntPtrTy->getBitWidth())
932 SetAbsRange(~0ull, ~0ull);
934 SetAbsRange(0, 1ull << AbsWidth);
939 TIL.OffsetedGlobal = ImportGlobal(
"global_addr");
944 TIL.AlignLog2 = ImportConstant(
"align", TTRes.
AlignLog2, 8, Int8Ty);
950 TIL.TheByteArray = ImportGlobal(
"byte_array");
951 TIL.BitMask = ImportConstant(
"bit_mask", TTRes.
BitMask, 8, Int8PtrTy);
955 TIL.InlineBits = ImportConstant(
962 void LowerTypeTestsModule::importTypeTest(
CallInst *CI) {
970 "Second argument of llvm.type.test must be a metadata string");
972 TypeIdLowering TIL = importTypeId(TypeIdStr->getString());
973 Value *Lowered = lowerTypeTestCall(TypeIdStr, CI, TIL);
980 void LowerTypeTestsModule::importFunction(
Function *
F,
bool isDefinition) {
995 replaceDirectCalls(F, RealF);
1006 }
else if (isDefinition) {
1017 for (
auto &U : F->
uses()) {
1018 if (
auto *A = dyn_cast<GlobalAlias>(U.getUser())) {
1023 A->replaceAllUsesWith(AliasDecl);
1027 for (
auto *A : ToErase)
1028 A->eraseFromParent();
1039 replaceWeakDeclarationWithJumpTablePtr(F, FDecl, isDefinition);
1041 replaceCfiUses(F, FDecl, isDefinition);
1048 void LowerTypeTestsModule::lowerTypeTestCalls(
1056 BitSetInfo BSI = buildBitSet(TypeId, GlobalLayout);
1058 if (
auto MDS = dyn_cast<MDString>(TypeId))
1059 dbgs() << MDS->getString() <<
": ";
1061 dbgs() <<
"<unnamed>: ";
1065 ByteArrayInfo *BAI =
nullptr;
1074 }
else if (BSI.
BitSize <= 64) {
1076 uint64_t InlineBits = 0;
1078 InlineBits |= uint64_t(1) <<
Bit;
1079 if (InlineBits == 0)
1086 ++NumByteArraysCreated;
1087 BAI = createByteArray(BSI);
1088 TIL.TheByteArray = BAI->ByteArray;
1089 TIL.BitMask = BAI->MaskGlobal;
1092 TypeIdUserInfo &TIUI = TypeIdUsers[TypeId];
1094 if (TIUI.IsExported) {
1095 uint8_t *MaskPtr = exportTypeId(cast<MDString>(TypeId)->getString(), TIL);
1097 BAI->MaskPtr = MaskPtr;
1101 for (
CallInst *CI : TIUI.CallSites) {
1102 ++NumTypeTestCallsLowered;
1103 Value *Lowered = lowerTypeTestCall(TypeId, CI, TIL);
1116 if (isa<GlobalVariable>(GO) && GO->
hasSection())
1118 "A member of a type identifier may not have an explicit section");
1135 unsigned LowerTypeTestsModule::getJumpTableEntrySize() {
1152 void LowerTypeTestsModule::createJumpTableEntry(
1156 unsigned ArgIndex = AsmArgs.
size();
1159 AsmOS <<
"jmp ${" << ArgIndex <<
":c}@plt\n";
1160 AsmOS <<
"int3\nint3\nint3\n";
1162 AsmOS <<
"b $" << ArgIndex <<
"\n";
1164 AsmOS <<
"b.w $" << ArgIndex <<
"\n";
1169 ConstraintOS << (ArgIndex > 0 ?
",s" :
"s");
1173 Type *LowerTypeTestsModule::getJumpTableEntryType() {
1179 void LowerTypeTestsModule::buildBitSetsFromFunctions(
1183 buildBitSetsFromFunctionsNative(TypeIds, Functions);
1185 buildBitSetsFromFunctionsWASM(TypeIds, Functions);
1190 void LowerTypeTestsModule::moveInitializerToModuleConstructor(
1192 if (WeakInitializerFn ==
nullptr) {
1197 M.getDataLayout().getProgramAddressSpace(),
1198 "__cfi_global_var_init", &M);
1202 WeakInitializerFn->setSection(
1204 ?
"__TEXT,__StaticInit,regular,pure_instructions" 1211 IRBuilder<> IRB(WeakInitializerFn->getEntryBlock().getTerminator());
1217 void LowerTypeTestsModule::findGlobalVariableUsersOf(
1219 for (
auto *U : C->
users()){
1220 if (
auto *GV = dyn_cast<GlobalVariable>(U))
1222 else if (
auto *C2 = dyn_cast<Constant>(U))
1223 findGlobalVariableUsersOf(C2, Out);
1228 void LowerTypeTestsModule::replaceWeakDeclarationWithJumpTablePtr(
1233 findGlobalVariableUsersOf(F, GlobalVarUsers);
1234 for (
auto GV : GlobalVarUsers)
1235 moveInitializerToModuleConstructor(GV);
1243 replaceCfiUses(F, PlaceholderFn, IsDefinition);
1259 if (Feature ==
"-thumb-mode")
1261 else if (Feature ==
"+thumb-mode")
1278 unsigned ArmCount = 0, ThumbCount = 0;
1279 for (
const auto GTM : Functions) {
1280 if (!GTM->isDefinition()) {
1286 Function *F = cast<Function>(GTM->getGlobal());
1293 void LowerTypeTestsModule::createJumpTable(
1295 std::string AsmStr, ConstraintStr;
1302 for (
unsigned I = 0;
I != Functions.
size(); ++
I)
1303 createJumpTableEntry(AsmOS, ConstraintOS, JumpTableArch, AsmArgs,
1304 cast<Function>(Functions[
I]->getGlobal()));
1315 F->
addFnAttr(
"target-features",
"-thumb-mode");
1317 F->
addFnAttr(
"target-features",
"+thumb-mode");
1320 F->
addFnAttr(
"target-cpu",
"cortex-a8");
1330 for (
const auto &
Arg : AsmArgs)
1334 AsmOS.str(), ConstraintOS.
str(),
1337 IRB.CreateCall(JumpTableAsm, AsmArgs);
1338 IRB.CreateUnreachable();
1343 void LowerTypeTestsModule::buildBitSetsFromFunctionsNative(
1425 unsigned EntrySize = getJumpTableEntrySize();
1426 for (
unsigned I = 0;
I != Functions.
size(); ++
I)
1427 GlobalLayout[Functions[
I]] =
I * EntrySize;
1433 M.getDataLayout().getProgramAddressSpace(),
1434 ".cfi.jumptable", &M);
1440 lowerTypeTestCalls(TypeIds, JumpTable, GlobalLayout);
1444 for (
unsigned I = 0;
I != Functions.
size(); ++
I) {
1445 Function *F = cast<Function>(Functions[
I]->getGlobal());
1446 bool IsDefinition = Functions[
I]->isDefinition();
1450 JumpTableType, JumpTable,
1454 if (Functions[
I]->isExported()) {
1456 ExportSummary->cfiFunctionDefs().insert(F->
getName());
1460 F->
getName() +
".cfi_jt", CombinedGlobalElemPtr, &M);
1462 ExportSummary->cfiFunctionDecls().insert(F->
getName());
1465 if (!IsDefinition) {
1467 replaceWeakDeclarationWithJumpTablePtr(F, CombinedGlobalElemPtr, IsDefinition);
1469 replaceCfiUses(F, CombinedGlobalElemPtr, IsDefinition);
1476 FAlias->takeName(F);
1477 if (FAlias->hasName())
1478 F->
setName(FAlias->getName() +
".cfi");
1479 replaceCfiUses(F, FAlias, IsDefinition);
1485 createJumpTable(JumpTableFn, Functions);
1494 void LowerTypeTestsModule::buildBitSetsFromFunctionsWASM(
1501 for (GlobalTypeMember *GTM : Functions) {
1502 Function *F = cast<Function>(GTM->getGlobal());
1515 GlobalLayout[GTM] = IndirectIndex++;
1524 void LowerTypeTestsModule::buildBitSetsFromDisjointSet(
1528 for (
unsigned I = 0;
I != TypeIds.
size(); ++
I)
1529 TypeIdIndices[TypeIds[
I]] =
I;
1533 std::vector<std::set<uint64_t>> TypeMembers(TypeIds.
size());
1534 unsigned GlobalIndex = 0;
1536 for (GlobalTypeMember *GTM : Globals) {
1537 for (
MDNode *Type : GTM->types()) {
1540 if (
I != TypeIdIndices.
end())
1541 TypeMembers[
I->second].insert(GlobalIndex);
1543 GlobalIndices[GTM] = GlobalIndex;
1547 for (ICallBranchFunnel *JT : ICallBranchFunnels) {
1548 TypeMembers.emplace_back();
1549 std::set<uint64_t> &TMSet = TypeMembers.back();
1550 for (GlobalTypeMember *
T : JT->targets())
1551 TMSet.
insert(GlobalIndices[
T]);
1557 TypeMembers.begin(), TypeMembers.end(),
1558 [](
const std::set<uint64_t> &O1,
const std::set<uint64_t> &O2) {
1559 return O1.size() < O2.size();
1566 for (
auto &&MemSet : TypeMembers)
1571 Globals.empty() || isa<GlobalVariable>(Globals[0]->getGlobal());
1572 std::vector<GlobalTypeMember *> OrderedGTMs(Globals.size());
1573 auto OGTMI = OrderedGTMs.begin();
1574 for (
auto &&F : GLB.Fragments) {
1575 for (
auto &&
Offset : F) {
1576 if (IsGlobalSet != isa<GlobalVariable>(Globals[
Offset]->getGlobal()))
1578 "variables and functions");
1579 *OGTMI++ = Globals[
Offset];
1585 buildBitSetsFromGlobalVariables(TypeIds, OrderedGTMs);
1587 buildBitSetsFromFunctions(TypeIds, OrderedGTMs);
1591 LowerTypeTestsModule::LowerTypeTestsModule(
1594 : M(M), ExportSummary(ExportSummary), ImportSummary(ImportSummary) {
1595 assert(!(ExportSummary && ImportSummary));
1597 Arch = TargetTriple.
getArch();
1598 OS = TargetTriple.getOS();
1599 ObjectFormat = TargetTriple.getObjectFormat();
1602 bool LowerTypeTestsModule::runForTesting(
Module &M) {
1610 auto ReadSummaryFile =
1613 yaml::Input
In(ReadSummaryFile->getBuffer());
1619 LowerTypeTestsModule(
1631 yaml::Output Out(OS);
1648 void LowerTypeTestsModule::replaceCfiUses(
Function *Old,
Value *New,
bool IsDefinition) {
1656 if (isa<BlockAddress>(U.
getUser()))
1665 if (
auto *C = dyn_cast<Constant>(U.
getUser())) {
1666 if (!isa<GlobalValue>(C)) {
1678 for (
auto *C : Constants)
1682 void LowerTypeTestsModule::replaceDirectCalls(
Value *Old,
Value *New) {
1695 bool LowerTypeTestsModule::lower() {
1700 if ((!TypeTestFunc || TypeTestFunc->
use_empty()) &&
1701 (!ICallBranchFunnelFunc || ICallBranchFunnelFunc->
use_empty()) &&
1702 !ExportSummary && !ImportSummary)
1707 if (TypeTestFunc && !TypeTestFunc->
use_empty() &&
1712 if (ImportSummary) {
1716 auto *CI = cast<CallInst>((*UI++).getUser());
1721 if (ICallBranchFunnelFunc && !ICallBranchFunnelFunc->
use_empty())
1723 "unexpected call to llvm.icall.branch.funnel during import phase");
1739 importFunction(F,
true);
1740 for (
auto F : Decls)
1741 importFunction(F,
false);
1751 GlobalClassesTy GlobalClasses;
1763 std::vector<GlobalTypeMember *> RefGlobals;
1766 unsigned CurUniqueId = 0;
1771 const bool CrossDsoCfi = M.
getModuleFlag(
"Cross-DSO CFI") !=
nullptr;
1773 struct ExportedFunctionInfo {
1778 if (ExportSummary) {
1781 for (
auto &
I : *ExportSummary)
1782 for (
auto &GVS :
I.second.SummaryList)
1784 for (
auto &
Ref : GVS->refs())
1788 if (CfiFunctionsMD) {
1789 for (
auto FuncMD : CfiFunctionsMD->
operands()) {
1790 assert(FuncMD->getNumOperands() >= 2);
1792 cast<MDString>(FuncMD->getOperand(0))->getString();
1794 cast<ConstantAsMetadata>(FuncMD->getOperand(1))
1796 ->getUniqueInteger()
1802 if (!ExportSummary->isGUIDLive(GUID))
1804 if (!AddressTaken.
count(GUID)) {
1808 bool Exported =
false;
1809 if (
auto VI = ExportSummary->getValueInfo(GUID))
1810 for (
auto &GVS :
VI.getSummaryList())
1817 auto P = ExportedFunctions.
insert({FunctionName, {Linkage, FuncMD}});
1819 P.first->second = {Linkage, FuncMD};
1822 for (
const auto &
P : ExportedFunctions) {
1825 MDNode *FuncMD =
P.second.FuncMD;
1876 bool IsExported =
false;
1877 if (
Function *F = dyn_cast<Function>(&GO)) {
1892 GlobalTypeMember::create(Alloc, &GO, IsDefinition, IsExported, Types);
1893 GlobalTypeMembers[&GO] = GTM;
1894 for (
MDNode *Type : Types) {
1895 verifyTypeMDNode(&GO, Type);
1897 Info.UniqueId = ++CurUniqueId;
1898 Info.RefGlobals.push_back(GTM);
1902 auto AddTypeIdUse = [&](
Metadata *TypeId) -> TypeIdUserInfo & {
1907 auto Ins = TypeIdUsers.insert({TypeId, {}});
1910 GlobalClassesTy::iterator GCI = GlobalClasses.insert(TypeId);
1911 GlobalClassesTy::member_iterator CurSet = GlobalClasses.findLeader(GCI);
1914 for (GlobalTypeMember *GTM : TypeIdInfo[TypeId].RefGlobals)
1915 CurSet = GlobalClasses.unionSets(
1916 CurSet, GlobalClasses.findLeader(GlobalClasses.insert(GTM)));
1919 return Ins.first->second;
1923 for (
const Use &U : TypeTestFunc->
uses()) {
1924 auto CI = cast<CallInst>(U.getUser());
1929 auto TypeId = TypeIdMDVal->getMetadata();
1930 AddTypeIdUse(TypeId).CallSites.push_back(CI);
1934 if (ICallBranchFunnelFunc) {
1935 for (
const Use &U : ICallBranchFunnelFunc->
uses()) {
1938 "llvm.icall.branch.funnel not supported on this target");
1940 auto CI = cast<CallInst>(U.getUser());
1942 std::vector<GlobalTypeMember *> Targets;
1946 GlobalClassesTy::member_iterator CurSet;
1953 "Expected branch funnel operand to be global value");
1955 GlobalTypeMember *GTM = GlobalTypeMembers[
Base];
1956 Targets.push_back(GTM);
1957 GlobalClassesTy::member_iterator NewSet =
1958 GlobalClasses.findLeader(GlobalClasses.insert(GTM));
1962 CurSet = GlobalClasses.unionSets(CurSet, NewSet);
1965 GlobalClasses.unionSets(
1966 CurSet, GlobalClasses.findLeader(
1967 GlobalClasses.insert(ICallBranchFunnel::create(
1968 Alloc, CI, Targets, ++CurUniqueId))));
1972 if (ExportSummary) {
1974 for (
auto &
P : TypeIdInfo) {
1975 if (
auto *TypeId = dyn_cast<MDString>(
P.first))
1980 for (
auto &
P : *ExportSummary) {
1981 for (
auto &S :
P.second.SummaryList) {
1982 if (!ExportSummary->isGlobalValueLive(S.get()))
1984 if (
auto *FS = dyn_cast<FunctionSummary>(S->getBaseObject()))
1987 AddTypeIdUse(MD).IsExported =
true;
1992 if (GlobalClasses.empty())
1997 std::vector<std::pair<GlobalClassesTy::iterator, unsigned>> Sets;
1998 for (GlobalClassesTy::iterator
I = GlobalClasses.begin(),
1999 E = GlobalClasses.end();
2003 ++NumTypeIdDisjointSets;
2005 unsigned MaxUniqueId = 0;
2006 for (GlobalClassesTy::member_iterator
MI = GlobalClasses.member_begin(
I);
2007 MI != GlobalClasses.member_end(); ++
MI) {
2009 MaxUniqueId =
std::max(MaxUniqueId, TypeIdInfo[MD].UniqueId);
2010 else if (
auto *BF =
MI->dyn_cast<ICallBranchFunnel *>())
2011 MaxUniqueId =
std::max(MaxUniqueId, BF->UniqueId);
2013 Sets.emplace_back(
I, MaxUniqueId);
2016 [](
const std::pair<GlobalClassesTy::iterator, unsigned> &S1,
2017 const std::pair<GlobalClassesTy::iterator, unsigned> &S2) {
2018 return S1.second < S2.second;
2022 for (
const auto &S : Sets) {
2024 std::vector<Metadata *> TypeIds;
2025 std::vector<GlobalTypeMember *> Globals;
2026 std::vector<ICallBranchFunnel *> ICallBranchFunnels;
2027 for (GlobalClassesTy::member_iterator
MI =
2028 GlobalClasses.member_begin(S.first);
2029 MI != GlobalClasses.member_end(); ++
MI) {
2032 else if (
MI->is<GlobalTypeMember *>())
2033 Globals.push_back(
MI->get<GlobalTypeMember *>());
2035 ICallBranchFunnels.push_back(
MI->get<ICallBranchFunnel *>());
2041 return TypeIdInfo[M1].UniqueId < TypeIdInfo[M2].UniqueId;
2046 [&](ICallBranchFunnel *F1, ICallBranchFunnel *F2) {
2047 return F1->UniqueId < F2->UniqueId;
2051 buildBitSetsFromDisjointSet(TypeIds, Globals, ICallBranchFunnels);
2054 allocateByteArrays();
2058 if (ExportSummary) {
2060 for (
auto AliasMD : AliasesMD->operands()) {
2061 assert(AliasMD->getNumOperands() >= 4);
2063 cast<MDString>(AliasMD->getOperand(0))->getString();
2064 StringRef Aliasee = cast<MDString>(AliasMD->getOperand(1))->getString();
2066 if (!ExportedFunctions.
count(Aliasee) ||
2073 cast<ConstantAsMetadata>(AliasMD->getOperand(2))
2075 ->getUniqueInteger()
2078 static_cast<bool>(cast<ConstantAsMetadata>(AliasMD->getOperand(3))
2080 ->getUniqueInteger()
2093 Alias->setName(AliasName);
2100 if (ExportSummary) {
2102 for (
auto Symver : SymversMD->operands()) {
2103 assert(Symver->getNumOperands() >= 2);
2105 cast<MDString>(Symver->getOperand(0))->getString();
2106 StringRef Alias = cast<MDString>(Symver->getOperand(1))->getString();
2108 if (!ExportedFunctions.
count(SymbolName))
2112 (
llvm::Twine(
".symver ") + SymbolName +
", " + Alias).str());
2122 bool Changed = LowerTypeTestsModule(M, ExportSummary, ImportSummary).lower();
void setVisibility(VisibilityTypes V)
bool isDeclarationForLinker() const
This class implements a layout algorithm for globals referenced by bit sets that tries to keep member...
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
unsigned getAlignment() const
A parsed version of the target data layout string in and methods for querying it. ...
static ConstantInt * getFalse(LLVMContext &Context)
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
void ReplaceInstWithInst(BasicBlock::InstListType &BIL, BasicBlock::iterator &BI, Instruction *I)
Replace the instruction specified by BI with the instruction specified by I.
iterator_range< use_iterator > uses()
This class is used to build a byte array containing overlapping bit sets.
static IntegerType * getInt1Ty(LLVMContext &C)
bool hasLocalLinkage() const
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
uint64_t GUID
Declare a type to represent a global unique identifier for a global value.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
A Module instance is used to store all the information related to an LLVM module. ...
static cl::opt< bool > AvoidReuse("lowertypetests-avoid-reuse", cl::desc("Try to avoid reuse of byte array addresses using aliases"), cl::Hidden, cl::init(true))
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant *> IdxList, bool InBounds=false, Optional< unsigned > InRangeIndex=None, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
Unsatisfiable type (i.e. no global has this type metadata)
Implements a dense probed hash-table based set.
const StructLayout * getStructLayout(StructType *Ty) const
Returns a StructLayout object, indicating the alignment of the struct, its size, and the offsets of i...
void push_back(const T &Elt)
static ConstantAggregateZero * get(Type *Ty)
void allocate(const std::set< uint64_t > &Bits, uint64_t BitSize, uint64_t &AllocByteOffset, uint8_t &AllocMask)
Allocate BitSize bits in the byte array where Bits contains the bits to set.
Helper for check-and-exit error handling.
void print(raw_ostream &OS) const
This class represents a function call, abstracting a target machine's calling convention.
bool hasAvailableExternallyLinkage() const
const FeatureBitset Features
static Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
CfiFunctionLinkage
The type of CFI jumptable needed for a function.
Like Internal, but omit from symbol table.
Externally visible function.
void addOffset(uint64_t Offset)
unsigned getPointerSizeInBits(unsigned AS=0) const
Layout pointer size, in bits FIXME: The defaults need to be removed once all of the backends/clients ...
STATISTIC(NumFunctions, "Total number of functions")
const MDOperand & getOperand(unsigned I) const
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
ELFYAML::ELF_STV Visibility
static IntegerType * getInt64Ty(LLVMContext &C)
bool hasExternalWeakLinkage() const
static Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
Kind
Specifies which kind of type check we should emit for this byte array.
Value * CreateICmpULE(Value *LHS, Value *RHS, const Twine &Name="")
This defines the Use class.
void reserve(size_type N)
void setAlignment(unsigned Align)
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
static bool isLocalLinkage(LinkageTypes Linkage)
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
bool partiallySplitLTOUnits() const
Export information to summary.
iterator_range< global_object_iterator > global_objects()
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
Value * getArgOperand(unsigned i) const
static bool isKnownTypeIdMember(Metadata *TypeId, const DataLayout &DL, Value *V, uint64_t COffset)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
GlobalAlias * getNamedAlias(StringRef Name) const
Return the global alias in the module with the specified name, of arbitrary type. ...
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
amdgpu Simplify well known AMD library false Value Value const Twine & Name
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
StringRef getName(ID id)
Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
void initializeLowerTypeTestsPass(PassRegistry &)
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
void setInitializer(Constant *InitVal)
setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...
Class to represent struct types.
LLVMContext & getContext() const
Get the global data context.
A Use represents the edge between a Value definition and its users.
static const unsigned kX86JumpTableEntrySize
The returned value is undefined.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
The access may reference the value stored in memory.
MDNode * getMetadata(unsigned KindID) const
Get the current metadata attachments for the given kind, if any.
This file contains the simple types necessary to represent the attributes associated with functions a...
No attributes have been set.
void setName(const Twine &Name)
Change the name of the value.
This file implements a class to represent arbitrary precision integral constant values and operations...
static Constant * getZExt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
User * getUser() const LLVM_READONLY
Returns the User that contains this Use.
Type * getType() const
All values are typed, get the type of this value.
bool insert(const value_type &X)
Insert a new element into the SetVector.
static bool isThumbFunction(Function *F, Triple::ArchType ModuleArch)
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
BasicBlock * GetInsertBlock() const
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL)
Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset...
Class to represent array types.
VisibilityTypes
An enumeration for the kinds of visibility of global values.
void setComdat(Comdat *C)
static Constant * getSelect(Constant *C, Constant *V1, Constant *V2, Type *OnlyIfReducedTy=nullptr)
Select constant expr.
NamedMDNode * getNamedMetadata(const Twine &Name) const
Return the first NamedMDNode in the module with the specified name.
INITIALIZE_PASS(LowerTypeTests, "lowertypetests", "Lower type metadata", false, false) ModulePass *llvm
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
LinkageTypes getLinkage() const
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
bool containsGlobalOffset(uint64_t Offset) const
static bool isDirectCall(Use &U)
void takeName(Value *V)
Transfer the name from V to this value.
Class to hold module path string table and global value map, and encapsulate methods for operating on...
static cl::opt< PassSummaryAction > ClSummaryAction("lowertypetests-summary-action", cl::desc("What to do with the summary when running this pass"), cl::values(clEnumValN(PassSummaryAction::None, "none", "Do nothing"), clEnumValN(PassSummaryAction::Import, "import", "Import typeid resolutions from summary and globals"), clEnumValN(PassSummaryAction::Export, "export", "Export typeid resolutions to summary and globals")), cl::Hidden)
iterator_range< op_iterator > operands()
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block...
Value * getOperand(unsigned i) const
Analysis containing CSE Info
Class to represent pointers.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
static bool isWeakForLinker(LinkageTypes Linkage)
Whether the definition of this global may be replaced at link time.
iterator find(const_arg_type_t< KeyT > Val)
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
ExternalWeak linkage description.
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space...
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata *> MDs)
initializer< Ty > init(const Ty &Val)
bool hasAttribute(AttrKind Val) const
Return true if the attribute is present.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
A set of analyses that are preserved following a run of a transformation pass.
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1...
static Triple::ArchType selectJumpTableArmEncoding(ArrayRef< GlobalTypeMember *> Functions, Triple::ArchType ModuleArch)
VisibilityTypes getVisibility() const
Import information from summary.
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
Allocate memory in an ever growing pool, as if by bump-pointer.
Conditional or Unconditional Branch instruction.
Metadata * getModuleFlag(StringRef Key) const
Return the corresponding value if Key appears in module flags, otherwise return null.
static ManagedStatic< std::map< const Function *, ExFunc > > ExportedFunctions
void deleteBody()
deleteBody - This method deletes the body of the function, and converts the linkage to external...
size_t size() const
size - Get the array size.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * Allocate(size_t Size, size_t Alignment)
Allocate space at the specified alignment.
std::pair< iterator, bool > insert(const ValueT &V)
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it...
EquivalenceClasses - This represents a collection of equivalence classes and supports three efficient...
Expected< T > errorOrToExpected(ErrorOr< T > &&EO)
Convert an ErrorOr<T> to an Expected<T>.
static Type * getVoidTy(LLVMContext &C)
Single element (last example in "Short Inline Bit Vectors")
ModulePass * createLowerTypeTestsPass(ModuleSummaryIndex *ExportSummary, const ModuleSummaryIndex *ImportSummary)
This pass lowers type metadata and the llvm.type.test intrinsic to bitsets.
See the file comment for details on the usage of the TrailingObjects type.
unsigned getAddressSpace() const
static FunctionType * get(Type *Result, ArrayRef< Type *> Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
unsigned getAddressSpace() const
Return the address space of the Pointer type.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
static Constant * getICmp(unsigned short pred, Constant *LHS, Constant *RHS, bool OnlyIfReduced=false)
get* - Return some common constants without having to specify the full Instruction::OPCODE identifier...
self_iterator getIterator()
Class to represent integer types.
void setConstant(bool Val)
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
const Constant * stripPointerCasts() const
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
std::string & str()
Flushes the stream contents to the target string and returns the string's reference.
void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
Triple - Helper class for working with autoconf configuration names.
void sort(IteratorTy Start, IteratorTy End)
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateGEP(Value *Ptr, ArrayRef< Value *> IdxList, const Twine &Name="")
static Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
A SetVector that performs no allocations if smaller than a certain size.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the generic address space (address sp...
This is the shared class of boolean and integer constants.
bool hasSection() const
Check if this global has a custom object file section.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
void addMetadata(unsigned KindID, MDNode &MD)
Add a metadata attachment.
unsigned getProgramAddressSpace() const
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
static ConstantInt * getTrue(LLVMContext &Context)
void handleOperandChange(Value *, Value *)
This method is a special form of User::replaceUsesOfWith (which does not work on constants) that does...
void setLinkage(LinkageTypes LT)
enum llvm::TypeTestResolution::Kind TheKind
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Function * getFunction(StringRef Name) const
Look up the specified function in the module symbol table.
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Target - Wrapper for Target specific information.
Class for arbitrary precision integers.
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1', drop it.
iterator_range< user_iterator > users()
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
void setMetadata(unsigned KindID, MDNode *MD)
Set a particular kind of metadata attachment.
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
amdgpu Simplify well known AMD library false Value Value * Arg
Instruction * SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
uint64_t getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
std::set< std::string > & cfiFunctionDefs()
Test a byte array (first example)
A pointer union of three pointer types.
unsigned getNumArgOperands() const
A raw_ostream that writes to a file descriptor.
static IntegerType * getInt32Ty(LLVMContext &C)
StringRef getValueAsString() const
Return the attribute's value as a string.
All-ones bit vector ("Eliminating Bit Vector Checks for All-Ones Bit Vectors") ...
StringRef getName() const
Return a constant reference to the value's name.
static Constant * getInBoundsGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant *> IdxList)
Create an "inbounds" getelementptr.
static Constant * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
void appendModuleInlineAsm(StringRef Asm)
Append to the module-scope inline assembly blocks.
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Type * getValueType() const
Keep one copy of named function when linking (weak)
Rename collisions when linking (static functions).
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it...
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
static InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT)
InlineAsm::get - Return the specified uniqued inline asm string.
Inlined bit vector ("Short Inline Bit Vectors")
unsigned SizeM1BitWidth
Range of size-1 expressed as a bit width.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, int64_t FileSize=-1, bool RequiresNullTerminator=true, bool IsVolatile=false)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful, otherwise returning null.
bool hasAddressTaken(const User **=nullptr) const
hasAddressTaken - returns true if there are any uses of this function other than direct calls or invo...
static cl::opt< std::string > ClReadSummary("lowertypetests-read-summary", cl::desc("Read summary from given YAML file before running pass"), cl::Hidden)
ModuleSummaryIndex.h This file contains the declarations the classes that hold the module index and s...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::set< std::string > & cfiFunctionDecls()
user_iterator user_begin()
static Value * createMaskedBitTest(IRBuilder<> &B, Value *Bits, Value *BitOffset)
Build a test that bit BitOffset mod sizeof(Bits)*8 is set in Bits.
void addFragment(const std::set< uint64_t > &F)
Add F to the layout while trying to keep its indices contiguous.
A raw_ostream that writes to an std::string.
LLVM Value Representation.
This header defines support for implementing classes that have some trailing object (or arrays of obj...
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
static Constant * getAnon(ArrayRef< Constant *> V, bool Packed=false)
Return an anonymous struct that has the specified elements.
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
static Constant * get(LLVMContext &Context, ArrayRef< ElementTy > Elts)
get() constructor - Return a constant with array type with an element count and element type matching...
This class implements an extremely fast bulk output stream that can only output to a stream...
static const unsigned kARMJumpTableEntrySize
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
bool hasOneUse() const
Return true if there is exactly one user of this value.
StringRef - Represent a constant reference to a string, i.e.
A container for analyses that lazily runs them and caches their results.
bool eraseMetadata(unsigned KindID)
Erase all metadata attachments with the given kind.
std::set< uint64_t > Bits
This header defines various interfaces for pass management in LLVM.
static cl::opt< std::string > ClWriteSummary("lowertypetests-write-summary", cl::desc("Write summary to given YAML file after running pass"), cl::Hidden)
unsigned getNumOperands() const
Return number of MDNode operands.
static IntegerType * getInt8Ty(LLVMContext &C)
static GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
PointerType * getType() const
Global values are always pointers.
bool empty() const
empty - Check if the array is empty.
const BasicBlock * getParent() const
bool isCallee(Value::const_user_iterator UI) const
Determine whether the passed iterator points to the callee operand's Use.