@@ -870,26 +870,35 @@ JL_USED_FUNC static void dumpLivenessState(Function &F, State &S) {
870870 }
871871}
872872
873- // Check if this is a load from an immutable value. The easiest
874- // way to do so is to look at the tbaa and see if it derives from
875- // jtbaa_immut.
876- static bool isLoadFromImmut (LoadInst *LI)
873+ static bool isTBAA (MDNode *TBAA, std::initializer_list<const char *> const strset)
877874{
878- if (LI->getMetadata (LLVMContext::MD_invariant_load))
879- return true ;
880- MDNode *TBAA = LI->getMetadata (LLVMContext::MD_tbaa);
881875 if (!TBAA)
882876 return false ;
883877 while (TBAA->getNumOperands () > 1 ) {
884878 TBAA = cast<MDNode>(TBAA->getOperand (1 ).get ());
885879 auto str = cast<MDString>(TBAA->getOperand (0 ))->getString ();
886- if (str == " jtbaa_immut" || str == " jtbaa_const" ) {
887- return true ;
880+ for (auto str2 : strset) {
881+ if (str == str2) {
882+ return true ;
883+ }
888884 }
889885 }
890886 return false ;
891887}
892888
889+ // Check if this is a load from an immutable value. The easiest
890+ // way to do so is to look at the tbaa and see if it derives from
891+ // jtbaa_immut.
892+ static bool isLoadFromImmut (LoadInst *LI)
893+ {
894+ if (LI->getMetadata (LLVMContext::MD_invariant_load))
895+ return true ;
896+ MDNode *TBAA = LI->getMetadata (LLVMContext::MD_tbaa);
897+ if (isTBAA (TBAA, {" jtbaa_immut" , " jtbaa_const" }))
898+ return true ;
899+ return false ;
900+ }
901+
893902// Check if this is a load from an constant global.
894903static bool isLoadFromConstGV (LoadInst *LI)
895904{
@@ -898,14 +907,8 @@ static bool isLoadFromConstGV(LoadInst *LI)
898907 if (!isa<GlobalVariable>(LI->getPointerOperand ()->stripInBoundsOffsets ()))
899908 return false ;
900909 MDNode *TBAA = LI->getMetadata (LLVMContext::MD_tbaa);
901- if (!TBAA)
902- return false ;
903- while (TBAA->getNumOperands () > 1 ) {
904- TBAA = cast<MDNode>(TBAA->getOperand (1 ).get ());
905- if (cast<MDString>(TBAA->getOperand (0 ))->getString () == " jtbaa_const" ) {
906- return true ;
907- }
908- }
910+ if (isTBAA (TBAA, {" jtbaa_const" }))
911+ return true ;
909912 return false ;
910913}
911914
@@ -1650,6 +1653,40 @@ static inline void UpdatePtrNumbering(Value *From, Value *To, State *S)
16501653 }
16511654}
16521655
1656+ #if JL_LLVM_VERSION < 80000
1657+ MDNode *createMutableTBAAAccessTag (MDNode *Tag) {
1658+ MDNode *BaseType = cast<MDNode>(Tag->getOperand (0 ));
1659+ MDNode *AccessType = cast<MDNode>(Tag->getOperand (1 ));
1660+ Metadata *OffsetNode = Tag->getOperand (2 );
1661+ uint64_t Offset = mdconst::extract<ConstantInt>(OffsetNode)->getZExtValue ();
1662+
1663+ bool NewFormat = isa<MDNode>(AccessType->getOperand (0 ));
1664+
1665+ // See if the tag is already mutable.
1666+ unsigned ImmutabilityFlagOp = NewFormat ? 4 : 3 ;
1667+ if (Tag->getNumOperands () <= ImmutabilityFlagOp)
1668+ return Tag;
1669+
1670+ // If Tag is already mutable then return it.
1671+ Metadata *ImmutabilityFlagNode = Tag->getOperand (ImmutabilityFlagOp);
1672+ if (!mdconst::extract<ConstantInt>(ImmutabilityFlagNode)->getValue ())
1673+ return Tag;
1674+
1675+ // Otherwise, create another node.
1676+ if (!NewFormat)
1677+ return MDBuilder (Tag->getContext ()).createTBAAStructTagNode (BaseType, AccessType, Offset);
1678+
1679+ Metadata *SizeNode = Tag->getOperand (3 );
1680+ uint64_t Size = mdconst::extract<ConstantInt>(SizeNode)->getZExtValue ();
1681+ return MDBuilder (Tag->getContext ()).createTBAAAccessTag (BaseType, AccessType, Offset, Size);
1682+ }
1683+ #else
1684+ MDNode *createMutableTBAAAccessTag (MDNode *Tag) {
1685+ return MDBuilder (Tag->getContext ()).createMutableTBAAAccessTag (TBAA);
1686+ }
1687+ #endif
1688+
1689+
16531690bool LateLowerGCFrame::CleanupIR (Function &F, State *S) {
16541691 bool ChangesMade = false ;
16551692 // We create one alloca for all the jlcall frames that haven't been processed
@@ -1667,6 +1704,24 @@ bool LateLowerGCFrame::CleanupIR(Function &F, State *S) {
16671704 SmallVector<CallInst*, 16 > write_barriers;
16681705 for (BasicBlock &BB : F) {
16691706 for (auto it = BB.begin (); it != BB.end ();) {
1707+ Instruction *I = &*it;
1708+ if (isa<LoadInst>(I) || isa<StoreInst>(I)) {
1709+ // strip all constant alias information, as it might depend on the gc having
1710+ // preserved a gc root, which stops being true after this pass (#32215)
1711+ // we'd like to call RewriteStatepointsForGC::stripNonValidData here, but
1712+ // that function asserts that the GC strategy must be named either "statepoint-example" or "coreclr",
1713+ // while we don't give a name to our GC in the IR, and C++ scope rules prohibit us from using it,
1714+ // so instead we reimplement it here badly
1715+ if (I->getMetadata (LLVMContext::MD_invariant_load))
1716+ I->setMetadata (LLVMContext::MD_invariant_load, NULL );
1717+ if (MDNode *TBAA = I->getMetadata (LLVMContext::MD_tbaa)) {
1718+ if (TBAA->getNumOperands () == 4 && isTBAA (TBAA, {" jtbaa_const" })) {
1719+ MDNode *MutableTBAA = createMutableTBAAAccessTag (TBAA);
1720+ if (MutableTBAA != TBAA)
1721+ I->setMetadata (LLVMContext::MD_tbaa, MutableTBAA);
1722+ }
1723+ }
1724+ }
16701725 auto *CI = dyn_cast<CallInst>(&*it);
16711726 if (!CI) {
16721727 ++it;
@@ -1745,18 +1800,18 @@ bool LateLowerGCFrame::CleanupIR(Function &F, State *S) {
17451800 else if (CC == JLCALL_F2_CC)
17461801 nframeargs -= 2 ;
17471802 SmallVector<Value*, 4 > ReplacementArgs;
1748- auto it = CI->arg_begin ();
1749- assert (it != CI->arg_end ());
1750- ReplacementArgs.push_back (*(it ++));
1803+ auto arg_it = CI->arg_begin ();
1804+ assert (arg_it != CI->arg_end ());
1805+ ReplacementArgs.push_back (*(arg_it ++));
17511806 if (CC != JLCALL_F_CC) {
1752- assert (it != CI->arg_end ());
1753- ReplacementArgs.push_back (*(it ++));
1807+ assert (arg_it != CI->arg_end ());
1808+ ReplacementArgs.push_back (*(arg_it ++));
17541809 }
17551810 maxframeargs = std::max (maxframeargs, nframeargs);
17561811 int slot = 0 ;
17571812 IRBuilder<> Builder (CI);
1758- for (; it != CI->arg_end (); ++it ) {
1759- Builder.CreateStore (*it , Builder.CreateGEP (T_prjlvalue, Frame,
1813+ for (; arg_it != CI->arg_end (); ++arg_it ) {
1814+ Builder.CreateStore (*arg_it , Builder.CreateGEP (T_prjlvalue, Frame,
17601815 ConstantInt::get (T_int32, slot++)));
17611816 }
17621817 ReplacementArgs.push_back (nframeargs == 0 ?
0 commit comments