Index: include/llvm/CodeGen/StackMaps.h =================================================================== --- include/llvm/CodeGen/StackMaps.h +++ include/llvm/CodeGen/StackMaps.h @@ -137,9 +137,13 @@ unsigned Size; unsigned Reg; int64_t Offset; - Location() : LocType(Unprocessed), Size(0), Reg(0), Offset(0) {} + const MCSymbol *Sym; + Location() : LocType(Unprocessed), Size(0), Reg(0), Offset(0), Sym(0) {} Location(LocationType LocType, unsigned Size, unsigned Reg, int64_t Offset) - : LocType(LocType), Size(Size), Reg(Reg), Offset(Offset) {} + : LocType(LocType), Size(Size), Reg(Reg), Offset(Offset), Sym(0) {} + Location(const MCSymbol *Sym) + : LocType(LocationType::Constant), Size(sizeof(int64_t)), Reg(0), + Offset(0), Sym(Sym) {} }; struct LiveOutReg { @@ -161,13 +165,19 @@ // OpTypes are used to encode information about the following logical // operand (which may consist of several MachineOperands) for the // OpParser. - typedef enum { DirectMemRefOp, IndirectMemRefOp, ConstantOp } OpType; + typedef enum { + DirectMemRefOp, + IndirectMemRefOp, + ConstantOp, + ConstantGVOp + } OpType; StackMaps(AsmPrinter &AP); void reset() { CSInfos.clear(); ConstPool.clear(); + ConstSymPool.clear(); FnStackSize.clear(); } @@ -192,6 +202,7 @@ typedef SmallVector LocationVec; typedef SmallVector LiveOutVec; typedef MapVector ConstantPool; + typedef MapVector ConstantSymMap; typedef MapVector FnStackSizeMap; struct CallsiteInfo { @@ -211,6 +222,7 @@ AsmPrinter &AP; CallsiteInfoList CSInfos; ConstantPool ConstPool; + ConstantSymMap ConstSymPool; FnStackSizeMap FnStackSize; MachineInstr::const_mop_iterator Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -6916,6 +6916,15 @@ const TargetLowering &TLI = Builder.DAG.getTargetLoweringInfo(); Ops.push_back( Builder.DAG.getTargetFrameIndex(FI->getIndex(), TLI.getPointerTy())); + } else if (auto *GA = dyn_cast(OpVal)) { + if (GA->getValueType(0) != MVT::i64) + Ops.push_back(OpVal); + else { + Ops.push_back( + Builder.DAG.getTargetConstant(StackMaps::ConstantGVOp, MVT::i64)); + Ops.push_back(Builder.DAG.getTargetGlobalAddress(GA->getGlobal(), + SDLoc(GA), MVT::i64)); + } } else Ops.push_back(OpVal); } Index: lib/CodeGen/StackMaps.cpp =================================================================== --- lib/CodeGen/StackMaps.cpp +++ lib/CodeGen/StackMaps.cpp @@ -118,6 +118,16 @@ Locs.push_back(Location(Location::Constant, sizeof(int64_t), 0, Imm)); break; } + case StackMaps::ConstantGVOp: { + ++MOI; + assert(MOI->isGlobal() && "Expected a global value operand."); + const GlobalValue *GV = MOI->getGlobal(); + assert(GV); + MCSymbol *Sym = AP.TM.getSymbol(GV, *AP.Mang); + assert(Sym); + Locs.push_back(Location(Sym)); + break; + } } return ++MOI; } @@ -296,7 +306,7 @@ I != E; ++I) { // Constants are encoded as sign-extended integers. // -1 is directly encoded as .long 0xFFFFFFFF with no constant pool. - if (I->LocType == Location::Constant && !isInt<32>(I->Offset)) { + if (I->LocType == Location::Constant && !isInt<32>(I->Offset) && !I->Sym) { I->LocType = Location::ConstantIndex; // ConstPool is intentionally a MapVector of 'uint64_t's (as // opposed to 'int64_t's). We should never be in a situation @@ -313,6 +323,17 @@ } } + // Convert constant symbols to ConstantIndex entries. + for (LocationVec::iterator I = Locations.begin(), E = Locations.end(); I != E; + ++I) { + if (I->LocType == Location::Constant && I->Sym) { + I->LocType = Location::ConstantIndex; + auto Result = ConstSymPool.insert(std::make_pair(I->Sym, I->Sym)); + // The symbolic entries will be emitted after the ConstPool entries. + I->Offset = ConstPool.size() + Result.first - ConstSymPool.begin(); + } + } + // Create an expression to calculate the offset of the callsite from function // entry. const MCExpr *CSOffsetExpr = MCBinaryExpr::CreateSub( @@ -395,8 +416,9 @@ DEBUG(dbgs() << WSMP << "#functions = " << FnStackSize.size() << '\n'); OS.EmitIntValue(FnStackSize.size(), 4); // Num constants. - DEBUG(dbgs() << WSMP << "#constants = " << ConstPool.size() << '\n'); - OS.EmitIntValue(ConstPool.size(), 4); + auto NumConst = ConstPool.size() + ConstSymPool.size(); + DEBUG(dbgs() << WSMP << "#constants = " << NumConst << '\n'); + OS.EmitIntValue(NumConst, 4); // Num callsites. DEBUG(dbgs() << WSMP << "#callsites = " << CSInfos.size() << '\n'); OS.EmitIntValue(CSInfos.size(), 4); @@ -429,6 +451,10 @@ DEBUG(dbgs() << WSMP << ConstEntry.second << '\n'); OS.EmitIntValue(ConstEntry.second, 8); } + for (auto ConstEntry : ConstSymPool) { + DEBUG(dbgs() << WSMP << ConstEntry.second << '\n'); + OS.EmitSymbolValue(ConstEntry.second, 8); + } } /// Emit the callsite info for each callsite. @@ -514,7 +540,8 @@ void StackMaps::serializeToStackMapSection() { (void) WSMP; // Bail out if there's no stack map data. - assert((!CSInfos.empty() || (CSInfos.empty() && ConstPool.empty())) && + assert((!CSInfos.empty() || + (CSInfos.empty() && ConstPool.empty() && ConstSymPool.empty())) && "Expected empty constant pool too!"); assert((!CSInfos.empty() || (CSInfos.empty() && FnStackSize.empty())) && "Expected empty function record too!"); @@ -543,4 +570,5 @@ // Clean up. CSInfos.clear(); ConstPool.clear(); + ConstSymPool.clear(); } Index: test/CodeGen/X86/stackmap.ll =================================================================== --- test/CodeGen/X86/stackmap.ll +++ test/CodeGen/X86/stackmap.ll @@ -11,7 +11,7 @@ ; Num Functions ; CHECK-NEXT: .long 16 ; Num LargeConstants -; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 5 ; Num Callsites ; CHECK-NEXT: .long 20 @@ -53,6 +53,8 @@ ; CHECK-NEXT: .quad 2147483648 ; CHECK-NEXT: .quad 4294967295 ; CHECK-NEXT: .quad 4294967296 +; CHECK-NEXT: .quad _constSym1 +; CHECK-NEXT: .quad _constSym2 ; Callsites ; Constant arguments @@ -60,7 +62,7 @@ ; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .long L{{.*}}-_constantargs ; CHECK-NEXT: .short 0 -; CHECK-NEXT: .short 12 +; CHECK-NEXT: .short 15 ; SmallConstant ; CHECK-NEXT: .byte 4 ; CHECK-NEXT: .byte 8 @@ -116,16 +118,34 @@ ; CHECK-NEXT: .byte 8 ; CHECK-NEXT: .short 0 ; CHECK-NEXT: .long 2 +; LargeConstant at index 3 +; CHECK-NEXT: .byte 5 +; CHECK-NEXT: .byte 8 +; CHECK-NEXT: .short 0 +; CHECK-NEXT: .long 3 +; LargeConstant at index 3 +; CHECK-NEXT: .byte 5 +; CHECK-NEXT: .byte 8 +; CHECK-NEXT: .short 0 +; CHECK-NEXT: .long 3 +; LargeConstant at index 4 +; CHECK-NEXT: .byte 5 +; CHECK-NEXT: .byte 8 +; CHECK-NEXT: .short 0 +; CHECK-NEXT: .long 4 ; SmallConstant ; CHECK-NEXT: .byte 4 ; CHECK-NEXT: .byte 8 ; CHECK-NEXT: .short 0 ; CHECK-NEXT: .long -1 + +@constSym1 = external constant i64 +@constSym2 = external constant i64 define void @constantargs() { entry: %0 = inttoptr i64 12345 to i8* - tail call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 1, i32 15, i8* %0, i32 0, i16 65535, i16 -1, i32 65536, i32 2000000000, i32 2147483647, i32 -1, i32 4294967295, i32 4294967296, i64 2147483648, i64 4294967295, i64 4294967296, i64 -1) + tail call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 1, i32 15, i8* %0, i32 0, i16 65535, i16 -1, i32 65536, i32 2000000000, i32 2147483647, i32 -1, i32 4294967295, i32 4294967296, i64 2147483648, i64 4294967295, i64 4294967296, i64* @constSym1, i64* @constSym1, i64* @constSym2, i64 -1) ret void }