LLVM 22.0.0git
systemz.cpp
Go to the documentation of this file.
1//===---- systemz.cpp - Generic JITLink systemz edge kinds, utilities -----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Generic utilities for graphs representing systemz objects.
10//
11//===----------------------------------------------------------------------===//
12
14
15#define DEBUG_TYPE "jitlink"
16
17namespace llvm {
18namespace jitlink {
19namespace systemz {
20
21const char NullPointerContent[8] = {0x00, 0x00, 0x00, 0x00,
22 0x00, 0x00, 0x00, 0x00};
23
24const char Pointer64JumpStubContent[8] = {
25 static_cast<char>(0xC4u),
26 0x18,
27 0x00,
28 0x00,
29 0x00,
30 0x00, // lgrl r1
31 static_cast<char>(0x07u),
32 static_cast<char>(0xF1u), // BCR 15, 1
33};
34
35const char *getEdgeKindName(Edge::Kind R) {
36 switch (R) {
37 case Pointer64:
38 return "Pointer64";
39 case Pointer32:
40 return "Pointer32";
41 case Pointer20:
42 return "Pointer20";
43 case Pointer16:
44 return "Pointer16";
45 case Pointer12:
46 return "Pointer12";
47 case Pointer8:
48 return "Pointer8";
49 case Delta64:
50 return "Delta64";
51 case Delta32:
52 return "Delta32";
53 case Delta16:
54 return "Delta16";
55 case Delta32dbl:
56 return "Delta32dbl";
57 case Delta24dbl:
58 return "Delta24dbl";
59 case Delta16dbl:
60 return "Delta16dbl";
61 case Delta12dbl:
62 return "Delta12dbl";
63 case NegDelta64:
64 return "NegDelta64";
65 case NegDelta32:
66 return "NegDelta32";
67 case DeltaPLT32dbl:
68 return "DeltaPLT32dbl";
69 case DeltaPLT24dbl:
70 return "DeltaPLT24dbl";
71 case DeltaPLT16dbl:
72 return "DeltaPLT16dbl";
73 case DeltaPLT12dbl:
74 return "DeltaPLT12dbl";
75 case DeltaPLT64:
76 return "DeltaPLT64";
77 case DeltaPLT32:
78 return "DeltaPLT32";
79 case Delta64FromGOT:
80 return "Delta64FromGOT";
81 case Delta32FromGOT:
82 return "Delta32FromGOT";
83 case Delta16FromGOT:
84 return "Delta16FromGOT";
86 return "Delta64PLTFromGOT";
88 return "Delta32PLTFromGOT";
90 return "Delta16PLTFromGOT";
91 case Delta32GOTBase:
92 return "Delta32GOTBase";
94 return "Delta32dblGOTBase";
96 return "RequestGOTAndTransformToDelta64FromGOT";
98 return "RequestGOTAndTransformToDelta32FromGOT";
100 return "RequestGOTAndTransformToDelta20FromGOT";
102 return "RequestGOTAndTransformToDelta16FromGOT";
104 return "RequestGOTAndTransformToDelta12FromGOT";
106 return "RequestGOTAndTransformToDelta32dbl";
108 return "RequestTLSDescInGOTAndTransformToDelta64FromGOT";
109 default:
110 return getGenericEdgeKindName(static_cast<Edge::Kind>(R));
111 }
112}
113
115 LLVM_DEBUG(dbgs() << "Optimizing GOT entries and stubs:\n");
116
117 for (auto *B : G.blocks())
118 for (auto &E : B->edges()) {
119 if (E.getKind() == systemz::DeltaPLT32dbl) {
120 auto &StubBlock = E.getTarget().getBlock();
121 if (StubBlock.getSize() == sizeof(Pointer64JumpStubContent) &&
122 StubBlock.edges_size() == 1) {
123 auto &GOTBlock = StubBlock.edges().begin()->getTarget().getBlock();
124 assert(GOTBlock.getSize() == G.getPointerSize() &&
125 "GOT block should be pointer sized");
126 assert(GOTBlock.edges_size() == 1 &&
127 "GOT block should only have one outgoing edge");
128
129 auto &GOTTarget = GOTBlock.edges().begin()->getTarget();
130 orc::ExecutorAddr EdgeAddr = B->getAddress() + E.getOffset();
131 orc::ExecutorAddr TargetAddr = GOTTarget.getAddress();
132
133 int64_t Displacement = TargetAddr + E.getAddend() - EdgeAddr;
134 if (isInt<33>(Displacement)) {
135 E.setKind(systemz::Delta32dbl);
136 E.setTarget(GOTTarget);
137 LLVM_DEBUG({
138 dbgs() << " Replaced stub branch with direct branch:\n ";
139 printEdge(dbgs(), *B, E, getEdgeKindName(E.getKind()));
140 dbgs() << "\n";
141 });
142 }
143 }
144 }
145 }
146
147 return Error::success();
148}
149
150} // namespace systemz
151} // namespace jitlink
152} // namespace llvm
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define G(x, y, z)
Definition MD5.cpp:55
#define LLVM_DEBUG(...)
Definition Debug.h:114
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Represents an address in the executor process.
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:165
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207