Skip to content

Commit 1a8b825

Browse files
committed
LowerTypeTests: Add import/export support for targets without absolute symbol constants.
The rationale is the same as for r312967. Differential Revision: https://reviews.llvm.org/D37408 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312968 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 37911b9 commit 1a8b825

File tree

16 files changed

+303
-93
lines changed

16 files changed

+303
-93
lines changed

include/llvm/IR/ModuleSummaryIndex.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,16 @@ struct TypeTestResolution {
487487
/// range [1,256], this number will be 8. This helps generate the most compact
488488
/// instruction sequences.
489489
unsigned SizeM1BitWidth = 0;
490+
491+
// The following fields are only used if the target does not support the use
492+
// of absolute symbols to store constants. Their meanings are the same as the
493+
// corresponding fields in LowerTypeTestsModule::TypeIdLowering in
494+
// LowerTypeTests.cpp.
495+
496+
uint64_t AlignLog2 = 0;
497+
uint64_t SizeM1 = 0;
498+
uint8_t BitMask = 0;
499+
uint64_t InlineBits = 0;
490500
};
491501

492502
struct WholeProgramDevirtResolution {

include/llvm/IR/ModuleSummaryIndexYAML.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ template <> struct MappingTraits<TypeTestResolution> {
3030
static void mapping(IO &io, TypeTestResolution &res) {
3131
io.mapOptional("Kind", res.TheKind);
3232
io.mapOptional("SizeM1BitWidth", res.SizeM1BitWidth);
33+
io.mapOptional("AlignLog2", res.AlignLog2);
34+
io.mapOptional("SizeM1", res.SizeM1);
35+
io.mapOptional("BitMask", res.BitMask);
36+
io.mapOptional("InlineBits", res.InlineBits);
3337
}
3438
};
3539

lib/LTO/LTO.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,11 @@ static void computeCacheKey(
217217
AddUnsigned(S.TTRes.TheKind);
218218
AddUnsigned(S.TTRes.SizeM1BitWidth);
219219

220+
AddUint64(S.TTRes.AlignLog2);
221+
AddUint64(S.TTRes.SizeM1);
222+
AddUint64(S.TTRes.BitMask);
223+
AddUint64(S.TTRes.InlineBits);
224+
220225
AddUint64(S.WPDRes.size());
221226
for (auto &WPD : S.WPDRes) {
222227
AddUnsigned(WPD.first);

lib/Transforms/IPO/LowerTypeTests.cpp

Lines changed: 68 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ struct ByteArrayInfo {
197197
uint64_t BitSize;
198198
GlobalVariable *ByteArray;
199199
GlobalVariable *MaskGlobal;
200+
uint8_t *MaskPtr = nullptr;
200201
};
201202

202203
/// A POD-like structure that we use to store a global reference together with
@@ -307,7 +308,8 @@ class LowerTypeTestsModule {
307308

308309
Function *WeakInitializerFn = nullptr;
309310

310-
void exportTypeId(StringRef TypeId, const TypeIdLowering &TIL);
311+
bool shouldExportConstantsAsAbsoluteSymbols();
312+
uint8_t *exportTypeId(StringRef TypeId, const TypeIdLowering &TIL);
311313
TypeIdLowering importTypeId(StringRef TypeId);
312314
void importTypeTest(CallInst *CI);
313315
void importFunction(Function *F, bool isDefinition);
@@ -474,6 +476,8 @@ void LowerTypeTestsModule::allocateByteArrays() {
474476
BAI->MaskGlobal->replaceAllUsesWith(
475477
ConstantExpr::getIntToPtr(ConstantInt::get(Int8Ty, Mask), Int8PtrTy));
476478
BAI->MaskGlobal->eraseFromParent();
479+
if (BAI->MaskPtr)
480+
*BAI->MaskPtr = Mask;
477481
}
478482

479483
Constant *ByteArrayConst = ConstantDataArray::get(M.getContext(), BAB.Bytes);
@@ -725,13 +729,21 @@ void LowerTypeTestsModule::buildBitSetsFromGlobalVariables(
725729
}
726730
}
727731

732+
bool LowerTypeTestsModule::shouldExportConstantsAsAbsoluteSymbols() {
733+
return (Arch == Triple::x86 || Arch == Triple::x86_64) &&
734+
ObjectFormat == Triple::ELF;
735+
}
736+
728737
/// Export the given type identifier so that ThinLTO backends may import it.
729738
/// Type identifiers are exported by adding coarse-grained information about how
730739
/// to test the type identifier to the summary, and creating symbols in the
731740
/// object file (aliases and absolute symbols) containing fine-grained
732741
/// information about the type identifier.
733-
void LowerTypeTestsModule::exportTypeId(StringRef TypeId,
734-
const TypeIdLowering &TIL) {
742+
///
743+
/// Returns a pointer to the location in which to store the bitmask, if
744+
/// applicable.
745+
uint8_t *LowerTypeTestsModule::exportTypeId(StringRef TypeId,
746+
const TypeIdLowering &TIL) {
735747
TypeTestResolution &TTRes =
736748
ExportSummary->getOrInsertTypeIdSummary(TypeId).TTRes;
737749
TTRes.TheKind = TIL.TheKind;
@@ -743,14 +755,21 @@ void LowerTypeTestsModule::exportTypeId(StringRef TypeId,
743755
GA->setVisibility(GlobalValue::HiddenVisibility);
744756
};
745757

758+
auto ExportConstant = [&](StringRef Name, uint64_t &Storage, Constant *C) {
759+
if (shouldExportConstantsAsAbsoluteSymbols())
760+
ExportGlobal(Name, ConstantExpr::getIntToPtr(C, Int8PtrTy));
761+
else
762+
Storage = cast<ConstantInt>(C)->getZExtValue();
763+
};
764+
746765
if (TIL.TheKind != TypeTestResolution::Unsat)
747766
ExportGlobal("global_addr", TIL.OffsetedGlobal);
748767

749768
if (TIL.TheKind == TypeTestResolution::ByteArray ||
750769
TIL.TheKind == TypeTestResolution::Inline ||
751770
TIL.TheKind == TypeTestResolution::AllOnes) {
752-
ExportGlobal("align", ConstantExpr::getIntToPtr(TIL.AlignLog2, Int8PtrTy));
753-
ExportGlobal("size_m1", ConstantExpr::getIntToPtr(TIL.SizeM1, Int8PtrTy));
771+
ExportConstant("align", TTRes.AlignLog2, TIL.AlignLog2);
772+
ExportConstant("size_m1", TTRes.SizeM1, TIL.SizeM1);
754773

755774
uint64_t BitSize = cast<ConstantInt>(TIL.SizeM1)->getZExtValue() + 1;
756775
if (TIL.TheKind == TypeTestResolution::Inline)
@@ -761,12 +780,16 @@ void LowerTypeTestsModule::exportTypeId(StringRef TypeId,
761780

762781
if (TIL.TheKind == TypeTestResolution::ByteArray) {
763782
ExportGlobal("byte_array", TIL.TheByteArray);
764-
ExportGlobal("bit_mask", TIL.BitMask);
783+
if (shouldExportConstantsAsAbsoluteSymbols())
784+
ExportGlobal("bit_mask", TIL.BitMask);
785+
else
786+
return &TTRes.BitMask;
765787
}
766788

767789
if (TIL.TheKind == TypeTestResolution::Inline)
768-
ExportGlobal("inline_bits",
769-
ConstantExpr::getIntToPtr(TIL.InlineBits, Int8PtrTy));
790+
ExportConstant("inline_bits", TTRes.InlineBits, TIL.InlineBits);
791+
792+
return nullptr;
770793
}
771794

772795
LowerTypeTestsModule::TypeIdLowering
@@ -779,16 +802,31 @@ LowerTypeTestsModule::importTypeId(StringRef TypeId) {
779802
TypeIdLowering TIL;
780803
TIL.TheKind = TTRes.TheKind;
781804

782-
auto ImportGlobal = [&](StringRef Name, unsigned AbsWidth) {
805+
auto ImportGlobal = [&](StringRef Name) {
783806
Constant *C =
784807
M.getOrInsertGlobal(("__typeid_" + TypeId + "_" + Name).str(), Int8Ty);
785-
auto *GV = dyn_cast<GlobalVariable>(C);
786-
// We only need to set metadata if the global is newly created, in which
787-
// case it would not have hidden visibility.
788-
if (!GV || GV->getVisibility() == GlobalValue::HiddenVisibility)
808+
if (auto *GV = dyn_cast<GlobalVariable>(C))
809+
GV->setVisibility(GlobalValue::HiddenVisibility);
810+
return C;
811+
};
812+
813+
auto ImportConstant = [&](StringRef Name, uint64_t Const, unsigned AbsWidth,
814+
Type *Ty) {
815+
if (!shouldExportConstantsAsAbsoluteSymbols()) {
816+
Constant *C =
817+
ConstantInt::get(isa<IntegerType>(Ty) ? Ty : Int64Ty, Const);
818+
if (!isa<IntegerType>(Ty))
819+
C = ConstantExpr::getIntToPtr(C, Ty);
820+
return C;
821+
}
822+
823+
Constant *C = ImportGlobal(Name);
824+
auto *GV = cast<GlobalVariable>(C->stripPointerCasts());
825+
if (isa<IntegerType>(Ty))
826+
C = ConstantExpr::getPtrToInt(C, Ty);
827+
if (GV->getMetadata(LLVMContext::MD_absolute_symbol))
789828
return C;
790829

791-
GV->setVisibility(GlobalValue::HiddenVisibility);
792830
auto SetAbsRange = [&](uint64_t Min, uint64_t Max) {
793831
auto *MinC = ConstantAsMetadata::get(ConstantInt::get(IntPtrTy, Min));
794832
auto *MaxC = ConstantAsMetadata::get(ConstantInt::get(IntPtrTy, Max));
@@ -797,30 +835,30 @@ LowerTypeTestsModule::importTypeId(StringRef TypeId) {
797835
};
798836
if (AbsWidth == IntPtrTy->getBitWidth())
799837
SetAbsRange(~0ull, ~0ull); // Full set.
800-
else if (AbsWidth)
838+
else
801839
SetAbsRange(0, 1ull << AbsWidth);
802840
return C;
803841
};
804842

805843
if (TIL.TheKind != TypeTestResolution::Unsat)
806-
TIL.OffsetedGlobal = ImportGlobal("global_addr", 0);
844+
TIL.OffsetedGlobal = ImportGlobal("global_addr");
807845

808846
if (TIL.TheKind == TypeTestResolution::ByteArray ||
809847
TIL.TheKind == TypeTestResolution::Inline ||
810848
TIL.TheKind == TypeTestResolution::AllOnes) {
811-
TIL.AlignLog2 = ConstantExpr::getPtrToInt(ImportGlobal("align", 8), Int8Ty);
812-
TIL.SizeM1 = ConstantExpr::getPtrToInt(
813-
ImportGlobal("size_m1", TTRes.SizeM1BitWidth), IntPtrTy);
849+
TIL.AlignLog2 = ImportConstant("align", TTRes.AlignLog2, 8, Int8Ty);
850+
TIL.SizeM1 =
851+
ImportConstant("size_m1", TTRes.SizeM1, TTRes.SizeM1BitWidth, IntPtrTy);
814852
}
815853

816854
if (TIL.TheKind == TypeTestResolution::ByteArray) {
817-
TIL.TheByteArray = ImportGlobal("byte_array", 0);
818-
TIL.BitMask = ImportGlobal("bit_mask", 8);
855+
TIL.TheByteArray = ImportGlobal("byte_array");
856+
TIL.BitMask = ImportConstant("bit_mask", TTRes.BitMask, 8, Int8PtrTy);
819857
}
820858

821859
if (TIL.TheKind == TypeTestResolution::Inline)
822-
TIL.InlineBits = ConstantExpr::getPtrToInt(
823-
ImportGlobal("inline_bits", 1 << TTRes.SizeM1BitWidth),
860+
TIL.InlineBits = ImportConstant(
861+
"inline_bits", TTRes.InlineBits, 1 << TTRes.SizeM1BitWidth,
824862
TTRes.SizeM1BitWidth <= 5 ? Int32Ty : Int64Ty);
825863

826864
return TIL;
@@ -899,6 +937,7 @@ void LowerTypeTestsModule::lowerTypeTestCalls(
899937
BSI.print(dbgs());
900938
});
901939

940+
ByteArrayInfo *BAI = nullptr;
902941
TypeIdLowering TIL;
903942
TIL.OffsetedGlobal = ConstantExpr::getGetElementPtr(
904943
Int8Ty, CombinedGlobalAddr, ConstantInt::get(IntPtrTy, BSI.ByteOffset)),
@@ -920,15 +959,18 @@ void LowerTypeTestsModule::lowerTypeTestCalls(
920959
} else {
921960
TIL.TheKind = TypeTestResolution::ByteArray;
922961
++NumByteArraysCreated;
923-
ByteArrayInfo *BAI = createByteArray(BSI);
962+
BAI = createByteArray(BSI);
924963
TIL.TheByteArray = BAI->ByteArray;
925964
TIL.BitMask = BAI->MaskGlobal;
926965
}
927966

928967
TypeIdUserInfo &TIUI = TypeIdUsers[TypeId];
929968

930-
if (TIUI.IsExported)
931-
exportTypeId(cast<MDString>(TypeId)->getString(), TIL);
969+
if (TIUI.IsExported) {
970+
uint8_t *MaskPtr = exportTypeId(cast<MDString>(TypeId)->getString(), TIL);
971+
if (BAI)
972+
BAI->MaskPtr = MaskPtr;
973+
}
932974

933975
// Lower each call to llvm.type.test for this type identifier.
934976
for (CallInst *CI : TIUI.CallSites) {

test/Transforms/LowerTypeTests/Inputs/import.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,42 @@ TypeIdMap:
44
TTRes:
55
Kind: AllOnes
66
SizeM1BitWidth: 7
7+
AlignLog2: 1
8+
SizeM1: 42
79
allones32:
810
TTRes:
911
Kind: AllOnes
1012
SizeM1BitWidth: 32
13+
AlignLog2: 2
14+
SizeM1: 12345
1115
bytearray7:
1216
TTRes:
1317
Kind: ByteArray
1418
SizeM1BitWidth: 7
19+
AlignLog2: 3
20+
SizeM1: 43
21+
BitMask: 64
1522
bytearray32:
1623
TTRes:
1724
Kind: ByteArray
1825
SizeM1BitWidth: 32
26+
AlignLog2: 4
27+
SizeM1: 12346
28+
BitMask: 128
1929
inline5:
2030
TTRes:
2131
Kind: Inline
2232
SizeM1BitWidth: 5
33+
AlignLog2: 5
34+
SizeM1: 31
35+
InlineBits: 123
2336
inline6:
2437
TTRes:
2538
Kind: Inline
2639
SizeM1BitWidth: 6
40+
AlignLog2: 6
41+
SizeM1: 63
42+
InlineBits: 1000000000000
2743
single:
2844
TTRes:
2945
Kind: Single

test/Transforms/LowerTypeTests/export-allones.ll

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
; RUN: opt -S -lowertypetests -lowertypetests-summary-action=export -lowertypetests-read-summary=%S/Inputs/use-typeid1-typeid2.yaml -lowertypetests-write-summary=%t < %s | FileCheck %s
2-
; RUN: FileCheck --check-prefix=SUMMARY %s < %t
1+
; RUN: opt -mtriple=x86_64-unknown-linux -S -lowertypetests -lowertypetests-summary-action=export -lowertypetests-read-summary=%S/Inputs/use-typeid1-typeid2.yaml -lowertypetests-write-summary=%t < %s | FileCheck --check-prefixes=CHECK,X86 %s
2+
; RUN: FileCheck --check-prefixes=SUMMARY,SUMMARY-X86 %s < %t
3+
4+
; RUN: opt -mtriple=aarch64-unknown-linux -S -lowertypetests -lowertypetests-summary-action=export -lowertypetests-read-summary=%S/Inputs/use-typeid1-typeid2.yaml -lowertypetests-write-summary=%t < %s | FileCheck --check-prefixes=CHECK,ARM %s
5+
; RUN: FileCheck --check-prefixes=SUMMARY,SUMMARY-ARM %s < %t
36

47
@foo = constant [2048 x i8] zeroinitializer, !type !0, !type !1, !type !2, !type !3, !type !4, !type !5, !type !6, !type !7, !type !8, !type !9, !type !10, !type !11, !type !12, !type !13, !type !14, !type !15, !type !16, !type !17, !type !18, !type !19, !type !20, !type !21, !type !22, !type !23, !type !24, !type !25, !type !26, !type !27, !type !28, !type !29, !type !30, !type !31, !type !32, !type !33, !type !34, !type !35, !type !36, !type !37, !type !38, !type !39, !type !40, !type !41, !type !42, !type !43, !type !44, !type !45, !type !46, !type !47, !type !48, !type !49, !type !50, !type !51, !type !52, !type !53, !type !54, !type !55, !type !56, !type !57, !type !58, !type !59, !type !60, !type !61, !type !62, !type !63, !type !64, !type !65, !type !66, !type !67, !type !68, !type !69, !type !70, !type !71, !type !72, !type !73, !type !74, !type !75, !type !76, !type !77, !type !78, !type !79, !type !80, !type !81, !type !82, !type !83, !type !84, !type !85, !type !86, !type !87, !type !88, !type !89, !type !90, !type !91, !type !92, !type !93, !type !94, !type !95, !type !96, !type !97, !type !98, !type !99, !type !100, !type !101, !type !102, !type !103, !type !104, !type !105, !type !106, !type !107, !type !108, !type !109, !type !110, !type !111, !type !112, !type !113, !type !114, !type !115, !type !116, !type !117, !type !118, !type !119, !type !120, !type !121, !type !122, !type !123, !type !124, !type !125, !type !126, !type !127, !type !128, !type !129, !type !130
58

@@ -139,12 +142,14 @@
139142
; CHECK: [[G:@[0-9]+]] = private constant { [2048 x i8] } zeroinitializer
140143

141144
; CHECK: @__typeid_typeid1_global_addr = hidden alias i8, getelementptr inbounds ({ [2048 x i8] }, { [2048 x i8] }* [[G]], i32 0, i32 0, i32 0)
142-
; CHECK: @__typeid_typeid1_align = hidden alias i8, inttoptr (i8 1 to i8*)
143-
; CHECK: @__typeid_typeid1_size_m1 = hidden alias i8, inttoptr (i64 1 to i8*)
145+
; X86: @__typeid_typeid1_align = hidden alias i8, inttoptr (i8 1 to i8*)
146+
; X86: @__typeid_typeid1_size_m1 = hidden alias i8, inttoptr (i64 1 to i8*)
144147

145148
; CHECK: @__typeid_typeid2_global_addr = hidden alias i8, getelementptr inbounds ({ [2048 x i8] }, { [2048 x i8] }* [[G]], i32 0, i32 0, i64 4)
146-
; CHECK: @__typeid_typeid2_align = hidden alias i8, inttoptr (i8 2 to i8*)
147-
; CHECK: @__typeid_typeid2_size_m1 = hidden alias i8, inttoptr (i64 128 to i8*)
149+
; X86: @__typeid_typeid2_align = hidden alias i8, inttoptr (i8 2 to i8*)
150+
; X86: @__typeid_typeid2_size_m1 = hidden alias i8, inttoptr (i64 128 to i8*)
151+
152+
; ARM-NOT: alias {{.*}} inttoptr
148153

149154
; CHECK: @foo = alias [2048 x i8], getelementptr inbounds ({ [2048 x i8] }, { [2048 x i8] }* [[G]], i32 0, i32 0)
150155

@@ -153,9 +158,25 @@
153158
; SUMMARY-NEXT: TTRes:
154159
; SUMMARY-NEXT: Kind: AllOnes
155160
; SUMMARY-NEXT: SizeM1BitWidth: 7
161+
; SUMMARY-X86-NEXT: AlignLog2: 0
162+
; SUMMARY-X86-NEXT: SizeM1: 0
163+
; SUMMARY-X86-NEXT: BitMask: 0
164+
; SUMMARY-X86-NEXT: InlineBits: 0
165+
; SUMMARY-ARM-NEXT: AlignLog2: 1
166+
; SUMMARY-ARM-NEXT: SizeM1: 1
167+
; SUMMARY-ARM-NEXT: BitMask: 0
168+
; SUMMARY-ARM-NEXT: InlineBits: 0
156169
; SUMMARY-NEXT: WPDRes:
157170
; SUMMARY-NEXT: typeid2:
158171
; SUMMARY-NEXT: TTRes:
159172
; SUMMARY-NEXT: Kind: AllOnes
160173
; SUMMARY-NEXT: SizeM1BitWidth: 32
174+
; SUMMARY-X86-NEXT: AlignLog2: 0
175+
; SUMMARY-X86-NEXT: SizeM1: 0
176+
; SUMMARY-X86-NEXT: BitMask: 0
177+
; SUMMARY-X86-NEXT: InlineBits: 0
178+
; SUMMARY-ARM-NEXT: AlignLog2: 2
179+
; SUMMARY-ARM-NEXT: SizeM1: 128
180+
; SUMMARY-ARM-NEXT: BitMask: 0
181+
; SUMMARY-ARM-NEXT: InlineBits: 0
161182
; SUMMARY-NEXT: WPDRes:

0 commit comments

Comments
 (0)