@@ -197,6 +197,7 @@ struct ByteArrayInfo {
197
197
uint64_t BitSize;
198
198
GlobalVariable *ByteArray;
199
199
GlobalVariable *MaskGlobal;
200
+ uint8_t *MaskPtr = nullptr ;
200
201
};
201
202
202
203
// / A POD-like structure that we use to store a global reference together with
@@ -307,7 +308,8 @@ class LowerTypeTestsModule {
307
308
308
309
Function *WeakInitializerFn = nullptr ;
309
310
310
- void exportTypeId (StringRef TypeId, const TypeIdLowering &TIL);
311
+ bool shouldExportConstantsAsAbsoluteSymbols ();
312
+ uint8_t *exportTypeId (StringRef TypeId, const TypeIdLowering &TIL);
311
313
TypeIdLowering importTypeId (StringRef TypeId);
312
314
void importTypeTest (CallInst *CI);
313
315
void importFunction (Function *F, bool isDefinition);
@@ -474,6 +476,8 @@ void LowerTypeTestsModule::allocateByteArrays() {
474
476
BAI->MaskGlobal ->replaceAllUsesWith (
475
477
ConstantExpr::getIntToPtr (ConstantInt::get (Int8Ty, Mask), Int8PtrTy));
476
478
BAI->MaskGlobal ->eraseFromParent ();
479
+ if (BAI->MaskPtr )
480
+ *BAI->MaskPtr = Mask;
477
481
}
478
482
479
483
Constant *ByteArrayConst = ConstantDataArray::get (M.getContext (), BAB.Bytes );
@@ -725,13 +729,21 @@ void LowerTypeTestsModule::buildBitSetsFromGlobalVariables(
725
729
}
726
730
}
727
731
732
+ bool LowerTypeTestsModule::shouldExportConstantsAsAbsoluteSymbols () {
733
+ return (Arch == Triple::x86 || Arch == Triple::x86_64) &&
734
+ ObjectFormat == Triple::ELF;
735
+ }
736
+
728
737
// / Export the given type identifier so that ThinLTO backends may import it.
729
738
// / Type identifiers are exported by adding coarse-grained information about how
730
739
// / to test the type identifier to the summary, and creating symbols in the
731
740
// / object file (aliases and absolute symbols) containing fine-grained
732
741
// / 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) {
735
747
TypeTestResolution &TTRes =
736
748
ExportSummary->getOrInsertTypeIdSummary (TypeId).TTRes ;
737
749
TTRes.TheKind = TIL.TheKind ;
@@ -743,14 +755,21 @@ void LowerTypeTestsModule::exportTypeId(StringRef TypeId,
743
755
GA->setVisibility (GlobalValue::HiddenVisibility);
744
756
};
745
757
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
+
746
765
if (TIL.TheKind != TypeTestResolution::Unsat)
747
766
ExportGlobal (" global_addr" , TIL.OffsetedGlobal );
748
767
749
768
if (TIL.TheKind == TypeTestResolution::ByteArray ||
750
769
TIL.TheKind == TypeTestResolution::Inline ||
751
770
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 );
754
773
755
774
uint64_t BitSize = cast<ConstantInt>(TIL.SizeM1 )->getZExtValue () + 1 ;
756
775
if (TIL.TheKind == TypeTestResolution::Inline)
@@ -761,12 +780,16 @@ void LowerTypeTestsModule::exportTypeId(StringRef TypeId,
761
780
762
781
if (TIL.TheKind == TypeTestResolution::ByteArray) {
763
782
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 ;
765
787
}
766
788
767
789
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 ;
770
793
}
771
794
772
795
LowerTypeTestsModule::TypeIdLowering
@@ -779,16 +802,31 @@ LowerTypeTestsModule::importTypeId(StringRef TypeId) {
779
802
TypeIdLowering TIL;
780
803
TIL.TheKind = TTRes.TheKind ;
781
804
782
- auto ImportGlobal = [&](StringRef Name, unsigned AbsWidth ) {
805
+ auto ImportGlobal = [&](StringRef Name) {
783
806
Constant *C =
784
807
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))
789
828
return C;
790
829
791
- GV->setVisibility (GlobalValue::HiddenVisibility);
792
830
auto SetAbsRange = [&](uint64_t Min, uint64_t Max) {
793
831
auto *MinC = ConstantAsMetadata::get (ConstantInt::get (IntPtrTy, Min));
794
832
auto *MaxC = ConstantAsMetadata::get (ConstantInt::get (IntPtrTy, Max));
@@ -797,30 +835,30 @@ LowerTypeTestsModule::importTypeId(StringRef TypeId) {
797
835
};
798
836
if (AbsWidth == IntPtrTy->getBitWidth ())
799
837
SetAbsRange (~0ull , ~0ull ); // Full set.
800
- else if (AbsWidth)
838
+ else
801
839
SetAbsRange (0 , 1ull << AbsWidth);
802
840
return C;
803
841
};
804
842
805
843
if (TIL.TheKind != TypeTestResolution::Unsat)
806
- TIL.OffsetedGlobal = ImportGlobal (" global_addr" , 0 );
844
+ TIL.OffsetedGlobal = ImportGlobal (" global_addr" );
807
845
808
846
if (TIL.TheKind == TypeTestResolution::ByteArray ||
809
847
TIL.TheKind == TypeTestResolution::Inline ||
810
848
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);
814
852
}
815
853
816
854
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 );
819
857
}
820
858
821
859
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 ,
824
862
TTRes.SizeM1BitWidth <= 5 ? Int32Ty : Int64Ty);
825
863
826
864
return TIL;
@@ -899,6 +937,7 @@ void LowerTypeTestsModule::lowerTypeTestCalls(
899
937
BSI.print (dbgs ());
900
938
});
901
939
940
+ ByteArrayInfo *BAI = nullptr ;
902
941
TypeIdLowering TIL;
903
942
TIL.OffsetedGlobal = ConstantExpr::getGetElementPtr (
904
943
Int8Ty, CombinedGlobalAddr, ConstantInt::get (IntPtrTy, BSI.ByteOffset )),
@@ -920,15 +959,18 @@ void LowerTypeTestsModule::lowerTypeTestCalls(
920
959
} else {
921
960
TIL.TheKind = TypeTestResolution::ByteArray;
922
961
++NumByteArraysCreated;
923
- ByteArrayInfo * BAI = createByteArray (BSI);
962
+ BAI = createByteArray (BSI);
924
963
TIL.TheByteArray = BAI->ByteArray ;
925
964
TIL.BitMask = BAI->MaskGlobal ;
926
965
}
927
966
928
967
TypeIdUserInfo &TIUI = TypeIdUsers[TypeId];
929
968
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
+ }
932
974
933
975
// Lower each call to llvm.type.test for this type identifier.
934
976
for (CallInst *CI : TIUI.CallSites ) {
0 commit comments