xref: /llvm-project/bolt/lib/Core/MCPlusBuilder.cpp (revision fd38366e4525c5507bbb2a2fc1f7d113a964224e)
1 //===- bolt/Core/MCPlusBuilder.cpp - Interface for MCPlus -----------------===//
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 // This file implements the MCPlusBuilder class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "bolt/Core/MCPlusBuilder.h"
14 #include "bolt/Core/MCPlus.h"
15 #include "bolt/Utils/CommandLineOpts.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCInst.h"
18 #include "llvm/MC/MCInstrAnalysis.h"
19 #include "llvm/MC/MCInstrDesc.h"
20 #include "llvm/MC/MCInstrInfo.h"
21 #include "llvm/MC/MCRegisterInfo.h"
22 #include "llvm/Support/CommandLine.h"
23 #include "llvm/Support/Debug.h"
24 #include <cstdint>
25 
26 #define DEBUG_TYPE "mcplus"
27 
28 using namespace llvm;
29 using namespace bolt;
30 using namespace MCPlus;
31 
32 namespace opts {
33 cl::opt<bool>
34     TerminalTrap("terminal-trap",
35                  cl::desc("Assume that execution stops at trap instruction"),
36                  cl::init(true), cl::Hidden, cl::cat(BoltCategory));
37 }
38 
equals(const MCInst & A,const MCInst & B,CompFuncTy Comp) const39 bool MCPlusBuilder::equals(const MCInst &A, const MCInst &B,
40                            CompFuncTy Comp) const {
41   if (A.getOpcode() != B.getOpcode())
42     return false;
43 
44   unsigned NumOperands = MCPlus::getNumPrimeOperands(A);
45   if (NumOperands != MCPlus::getNumPrimeOperands(B))
46     return false;
47 
48   for (unsigned Index = 0; Index < NumOperands; ++Index)
49     if (!equals(A.getOperand(Index), B.getOperand(Index), Comp))
50       return false;
51 
52   return true;
53 }
54 
equals(const MCOperand & A,const MCOperand & B,CompFuncTy Comp) const55 bool MCPlusBuilder::equals(const MCOperand &A, const MCOperand &B,
56                            CompFuncTy Comp) const {
57   if (A.isReg()) {
58     if (!B.isReg())
59       return false;
60     return A.getReg() == B.getReg();
61   } else if (A.isImm()) {
62     if (!B.isImm())
63       return false;
64     return A.getImm() == B.getImm();
65   } else if (A.isSFPImm()) {
66     if (!B.isSFPImm())
67       return false;
68     return A.getSFPImm() == B.getSFPImm();
69   } else if (A.isDFPImm()) {
70     if (!B.isDFPImm())
71       return false;
72     return A.getDFPImm() == B.getDFPImm();
73   } else if (A.isExpr()) {
74     if (!B.isExpr())
75       return false;
76     return equals(*A.getExpr(), *B.getExpr(), Comp);
77   } else {
78     llvm_unreachable("unexpected operand kind");
79     return false;
80   }
81 }
82 
equals(const MCExpr & A,const MCExpr & B,CompFuncTy Comp) const83 bool MCPlusBuilder::equals(const MCExpr &A, const MCExpr &B,
84                            CompFuncTy Comp) const {
85   if (A.getKind() != B.getKind())
86     return false;
87 
88   switch (A.getKind()) {
89   case MCExpr::Constant: {
90     const auto &ConstA = cast<MCConstantExpr>(A);
91     const auto &ConstB = cast<MCConstantExpr>(B);
92     return ConstA.getValue() == ConstB.getValue();
93   }
94 
95   case MCExpr::SymbolRef: {
96     const MCSymbolRefExpr &SymbolA = cast<MCSymbolRefExpr>(A);
97     const MCSymbolRefExpr &SymbolB = cast<MCSymbolRefExpr>(B);
98     return SymbolA.getKind() == SymbolB.getKind() &&
99            Comp(&SymbolA.getSymbol(), &SymbolB.getSymbol());
100   }
101 
102   case MCExpr::Unary: {
103     const auto &UnaryA = cast<MCUnaryExpr>(A);
104     const auto &UnaryB = cast<MCUnaryExpr>(B);
105     return UnaryA.getOpcode() == UnaryB.getOpcode() &&
106            equals(*UnaryA.getSubExpr(), *UnaryB.getSubExpr(), Comp);
107   }
108 
109   case MCExpr::Binary: {
110     const auto &BinaryA = cast<MCBinaryExpr>(A);
111     const auto &BinaryB = cast<MCBinaryExpr>(B);
112     return BinaryA.getOpcode() == BinaryB.getOpcode() &&
113            equals(*BinaryA.getLHS(), *BinaryB.getLHS(), Comp) &&
114            equals(*BinaryA.getRHS(), *BinaryB.getRHS(), Comp);
115   }
116 
117   case MCExpr::Target: {
118     const auto &TargetExprA = cast<MCTargetExpr>(A);
119     const auto &TargetExprB = cast<MCTargetExpr>(B);
120     return equals(TargetExprA, TargetExprB, Comp);
121   }
122   }
123 
124   llvm_unreachable("Invalid expression kind!");
125 }
126 
equals(const MCTargetExpr & A,const MCTargetExpr & B,CompFuncTy Comp) const127 bool MCPlusBuilder::equals(const MCTargetExpr &A, const MCTargetExpr &B,
128                            CompFuncTy Comp) const {
129   llvm_unreachable("target-specific expressions are unsupported");
130 }
131 
isTerminator(const MCInst & Inst) const132 bool MCPlusBuilder::isTerminator(const MCInst &Inst) const {
133   return Analysis->isTerminator(Inst) ||
134          (opts::TerminalTrap && Info->get(Inst.getOpcode()).isTrap());
135 }
136 
setTailCall(MCInst & Inst) const137 void MCPlusBuilder::setTailCall(MCInst &Inst) const {
138   assert(!hasAnnotation(Inst, MCAnnotation::kTailCall));
139   setAnnotationOpValue(Inst, MCAnnotation::kTailCall, true);
140 }
141 
isTailCall(const MCInst & Inst) const142 bool MCPlusBuilder::isTailCall(const MCInst &Inst) const {
143   if (hasAnnotation(Inst, MCAnnotation::kTailCall))
144     return true;
145   if (getConditionalTailCall(Inst))
146     return true;
147   return false;
148 }
149 
getEHInfo(const MCInst & Inst) const150 std::optional<MCLandingPad> MCPlusBuilder::getEHInfo(const MCInst &Inst) const {
151   if (!isCall(Inst))
152     return std::nullopt;
153   std::optional<int64_t> LPSym =
154       getAnnotationOpValue(Inst, MCAnnotation::kEHLandingPad);
155   if (!LPSym)
156     return std::nullopt;
157   std::optional<int64_t> Action =
158       getAnnotationOpValue(Inst, MCAnnotation::kEHAction);
159   if (!Action)
160     return std::nullopt;
161 
162   return std::make_pair(reinterpret_cast<const MCSymbol *>(*LPSym),
163                         static_cast<uint64_t>(*Action));
164 }
165 
addEHInfo(MCInst & Inst,const MCLandingPad & LP) const166 void MCPlusBuilder::addEHInfo(MCInst &Inst, const MCLandingPad &LP) const {
167   if (isCall(Inst)) {
168     assert(!getEHInfo(Inst));
169     setAnnotationOpValue(Inst, MCAnnotation::kEHLandingPad,
170                          reinterpret_cast<int64_t>(LP.first));
171     setAnnotationOpValue(Inst, MCAnnotation::kEHAction,
172                          static_cast<int64_t>(LP.second));
173   }
174 }
175 
updateEHInfo(MCInst & Inst,const MCLandingPad & LP) const176 bool MCPlusBuilder::updateEHInfo(MCInst &Inst, const MCLandingPad &LP) const {
177   if (!isInvoke(Inst))
178     return false;
179 
180   setAnnotationOpValue(Inst, MCAnnotation::kEHLandingPad,
181                        reinterpret_cast<int64_t>(LP.first));
182   setAnnotationOpValue(Inst, MCAnnotation::kEHAction,
183                        static_cast<int64_t>(LP.second));
184   return true;
185 }
186 
getGnuArgsSize(const MCInst & Inst) const187 int64_t MCPlusBuilder::getGnuArgsSize(const MCInst &Inst) const {
188   std::optional<int64_t> Value =
189       getAnnotationOpValue(Inst, MCAnnotation::kGnuArgsSize);
190   if (!Value)
191     return -1LL;
192   return *Value;
193 }
194 
addGnuArgsSize(MCInst & Inst,int64_t GnuArgsSize) const195 void MCPlusBuilder::addGnuArgsSize(MCInst &Inst, int64_t GnuArgsSize) const {
196   assert(GnuArgsSize >= 0 && "cannot set GNU_args_size to negative value");
197   assert(getGnuArgsSize(Inst) == -1LL && "GNU_args_size already set");
198   assert(isInvoke(Inst) && "GNU_args_size can only be set for invoke");
199 
200   setAnnotationOpValue(Inst, MCAnnotation::kGnuArgsSize, GnuArgsSize);
201 }
202 
getJumpTable(const MCInst & Inst) const203 uint64_t MCPlusBuilder::getJumpTable(const MCInst &Inst) const {
204   std::optional<int64_t> Value =
205       getAnnotationOpValue(Inst, MCAnnotation::kJumpTable);
206   if (!Value)
207     return 0;
208   return *Value;
209 }
210 
getJumpTableIndexReg(const MCInst & Inst) const211 uint16_t MCPlusBuilder::getJumpTableIndexReg(const MCInst &Inst) const {
212   return getAnnotationAs<uint16_t>(Inst, "JTIndexReg");
213 }
214 
setJumpTable(MCInst & Inst,uint64_t Value,uint16_t IndexReg,AllocatorIdTy AllocId)215 bool MCPlusBuilder::setJumpTable(MCInst &Inst, uint64_t Value,
216                                  uint16_t IndexReg, AllocatorIdTy AllocId) {
217   if (!isIndirectBranch(Inst))
218     return false;
219   setAnnotationOpValue(Inst, MCAnnotation::kJumpTable, Value);
220   getOrCreateAnnotationAs<uint16_t>(Inst, "JTIndexReg", AllocId) = IndexReg;
221   return true;
222 }
223 
unsetJumpTable(MCInst & Inst) const224 bool MCPlusBuilder::unsetJumpTable(MCInst &Inst) const {
225   if (!getJumpTable(Inst))
226     return false;
227   removeAnnotation(Inst, MCAnnotation::kJumpTable);
228   removeAnnotation(Inst, "JTIndexReg");
229   return true;
230 }
231 
232 std::optional<uint64_t>
getConditionalTailCall(const MCInst & Inst) const233 MCPlusBuilder::getConditionalTailCall(const MCInst &Inst) const {
234   std::optional<int64_t> Value =
235       getAnnotationOpValue(Inst, MCAnnotation::kConditionalTailCall);
236   if (!Value)
237     return std::nullopt;
238   return static_cast<uint64_t>(*Value);
239 }
240 
setConditionalTailCall(MCInst & Inst,uint64_t Dest) const241 bool MCPlusBuilder::setConditionalTailCall(MCInst &Inst, uint64_t Dest) const {
242   if (!isConditionalBranch(Inst))
243     return false;
244 
245   setAnnotationOpValue(Inst, MCAnnotation::kConditionalTailCall, Dest);
246   return true;
247 }
248 
unsetConditionalTailCall(MCInst & Inst) const249 bool MCPlusBuilder::unsetConditionalTailCall(MCInst &Inst) const {
250   if (!getConditionalTailCall(Inst))
251     return false;
252   removeAnnotation(Inst, MCAnnotation::kConditionalTailCall);
253   return true;
254 }
255 
getOffset(const MCInst & Inst) const256 std::optional<uint32_t> MCPlusBuilder::getOffset(const MCInst &Inst) const {
257   std::optional<int64_t> Value =
258       getAnnotationOpValue(Inst, MCAnnotation::kOffset);
259   if (!Value)
260     return std::nullopt;
261   return static_cast<uint32_t>(*Value);
262 }
263 
getOffsetWithDefault(const MCInst & Inst,uint32_t Default) const264 uint32_t MCPlusBuilder::getOffsetWithDefault(const MCInst &Inst,
265                                              uint32_t Default) const {
266   if (std::optional<uint32_t> Offset = getOffset(Inst))
267     return *Offset;
268   return Default;
269 }
270 
setOffset(MCInst & Inst,uint32_t Offset) const271 bool MCPlusBuilder::setOffset(MCInst &Inst, uint32_t Offset) const {
272   setAnnotationOpValue(Inst, MCAnnotation::kOffset, Offset);
273   return true;
274 }
275 
clearOffset(MCInst & Inst) const276 bool MCPlusBuilder::clearOffset(MCInst &Inst) const {
277   if (!hasAnnotation(Inst, MCAnnotation::kOffset))
278     return false;
279   removeAnnotation(Inst, MCAnnotation::kOffset);
280   return true;
281 }
282 
getInstLabel(const MCInst & Inst) const283 MCSymbol *MCPlusBuilder::getInstLabel(const MCInst &Inst) const {
284   if (std::optional<int64_t> Label =
285           getAnnotationOpValue(Inst, MCAnnotation::kLabel))
286     return reinterpret_cast<MCSymbol *>(*Label);
287   return nullptr;
288 }
289 
getOrCreateInstLabel(MCInst & Inst,const Twine & Name,MCContext * Ctx) const290 MCSymbol *MCPlusBuilder::getOrCreateInstLabel(MCInst &Inst, const Twine &Name,
291                                               MCContext *Ctx) const {
292   MCSymbol *Label = getInstLabel(Inst);
293   if (Label)
294     return Label;
295 
296   Label = Ctx->createNamedTempSymbol(Name);
297   setAnnotationOpValue(Inst, MCAnnotation::kLabel,
298                        reinterpret_cast<int64_t>(Label));
299   return Label;
300 }
301 
setInstLabel(MCInst & Inst,MCSymbol * Label) const302 void MCPlusBuilder::setInstLabel(MCInst &Inst, MCSymbol *Label) const {
303   assert(!getInstLabel(Inst) && "Instruction already has assigned label.");
304   setAnnotationOpValue(Inst, MCAnnotation::kLabel,
305                        reinterpret_cast<int64_t>(Label));
306 }
307 
getSize(const MCInst & Inst) const308 std::optional<uint32_t> MCPlusBuilder::getSize(const MCInst &Inst) const {
309   if (std::optional<int64_t> Value =
310           getAnnotationOpValue(Inst, MCAnnotation::kSize))
311     return static_cast<uint32_t>(*Value);
312   return std::nullopt;
313 }
314 
setSize(MCInst & Inst,uint32_t Size) const315 void MCPlusBuilder::setSize(MCInst &Inst, uint32_t Size) const {
316   setAnnotationOpValue(Inst, MCAnnotation::kSize, Size);
317 }
318 
isDynamicBranch(const MCInst & Inst) const319 bool MCPlusBuilder::isDynamicBranch(const MCInst &Inst) const {
320   if (!hasAnnotation(Inst, MCAnnotation::kDynamicBranch))
321     return false;
322   assert(isBranch(Inst) && "Branch expected.");
323   return true;
324 }
325 
326 std::optional<uint32_t>
getDynamicBranchID(const MCInst & Inst) const327 MCPlusBuilder::getDynamicBranchID(const MCInst &Inst) const {
328   if (std::optional<int64_t> Value =
329           getAnnotationOpValue(Inst, MCAnnotation::kDynamicBranch)) {
330     assert(isBranch(Inst) && "Branch expected.");
331     return static_cast<uint32_t>(*Value);
332   }
333   return std::nullopt;
334 }
335 
setDynamicBranch(MCInst & Inst,uint32_t ID) const336 void MCPlusBuilder::setDynamicBranch(MCInst &Inst, uint32_t ID) const {
337   assert(isBranch(Inst) && "Branch expected.");
338   setAnnotationOpValue(Inst, MCAnnotation::kDynamicBranch, ID);
339 }
340 
hasAnnotation(const MCInst & Inst,unsigned Index) const341 bool MCPlusBuilder::hasAnnotation(const MCInst &Inst, unsigned Index) const {
342   return (bool)getAnnotationOpValue(Inst, Index);
343 }
344 
removeAnnotation(MCInst & Inst,unsigned Index) const345 bool MCPlusBuilder::removeAnnotation(MCInst &Inst, unsigned Index) const {
346   std::optional<unsigned> FirstAnnotationOp = getFirstAnnotationOpIndex(Inst);
347   if (!FirstAnnotationOp)
348     return false;
349 
350   for (unsigned I = Inst.getNumOperands() - 1; I >= *FirstAnnotationOp; --I) {
351     const int64_t ImmValue = Inst.getOperand(I).getImm();
352     if (extractAnnotationIndex(ImmValue) == Index) {
353       Inst.erase(Inst.begin() + I);
354       return true;
355     }
356   }
357   return false;
358 }
359 
stripAnnotations(MCInst & Inst,bool KeepTC) const360 void MCPlusBuilder::stripAnnotations(MCInst &Inst, bool KeepTC) const {
361   KeepTC &= hasAnnotation(Inst, MCAnnotation::kTailCall);
362 
363   removeAnnotations(Inst);
364 
365   if (KeepTC)
366     setTailCall(Inst);
367 }
368 
printAnnotations(const MCInst & Inst,raw_ostream & OS) const369 void MCPlusBuilder::printAnnotations(const MCInst &Inst,
370                                      raw_ostream &OS) const {
371   std::optional<unsigned> FirstAnnotationOp = getFirstAnnotationOpIndex(Inst);
372   if (!FirstAnnotationOp)
373     return;
374 
375   for (unsigned I = *FirstAnnotationOp; I < Inst.getNumOperands(); ++I) {
376     const int64_t Imm = Inst.getOperand(I).getImm();
377     const unsigned Index = extractAnnotationIndex(Imm);
378     const int64_t Value = extractAnnotationValue(Imm);
379     const auto *Annotation = reinterpret_cast<const MCAnnotation *>(Value);
380     if (Index >= MCAnnotation::kGeneric) {
381       OS << " # " << AnnotationNames[Index - MCAnnotation::kGeneric] << ": ";
382       Annotation->print(OS);
383     }
384   }
385 }
386 
getClobberedRegs(const MCInst & Inst,BitVector & Regs) const387 void MCPlusBuilder::getClobberedRegs(const MCInst &Inst,
388                                      BitVector &Regs) const {
389   if (isPrefix(Inst) || isCFI(Inst))
390     return;
391 
392   const MCInstrDesc &InstInfo = Info->get(Inst.getOpcode());
393 
394   for (MCPhysReg ImplicitDef : InstInfo.implicit_defs())
395     Regs |= getAliases(ImplicitDef, /*OnlySmaller=*/false);
396 
397   for (const MCOperand &Operand : defOperands(Inst)) {
398     assert(Operand.isReg());
399     Regs |= getAliases(Operand.getReg(), /*OnlySmaller=*/false);
400   }
401 }
402 
getTouchedRegs(const MCInst & Inst,BitVector & Regs) const403 void MCPlusBuilder::getTouchedRegs(const MCInst &Inst, BitVector &Regs) const {
404   if (isPrefix(Inst) || isCFI(Inst))
405     return;
406 
407   const MCInstrDesc &InstInfo = Info->get(Inst.getOpcode());
408 
409   for (MCPhysReg ImplicitDef : InstInfo.implicit_defs())
410     Regs |= getAliases(ImplicitDef, /*OnlySmaller=*/false);
411   for (MCPhysReg ImplicitUse : InstInfo.implicit_uses())
412     Regs |= getAliases(ImplicitUse, /*OnlySmaller=*/false);
413 
414   for (unsigned I = 0, E = Inst.getNumOperands(); I != E; ++I) {
415     if (!Inst.getOperand(I).isReg())
416       continue;
417     Regs |= getAliases(Inst.getOperand(I).getReg(), /*OnlySmaller=*/false);
418   }
419 }
420 
getWrittenRegs(const MCInst & Inst,BitVector & Regs) const421 void MCPlusBuilder::getWrittenRegs(const MCInst &Inst, BitVector &Regs) const {
422   if (isPrefix(Inst) || isCFI(Inst))
423     return;
424 
425   const MCInstrDesc &InstInfo = Info->get(Inst.getOpcode());
426 
427   for (MCPhysReg ImplicitDef : InstInfo.implicit_defs())
428     Regs |= getAliases(ImplicitDef, /*OnlySmaller=*/true);
429 
430   for (const MCOperand &Operand : defOperands(Inst)) {
431     assert(Operand.isReg());
432     Regs |= getAliases(Operand.getReg(), /*OnlySmaller=*/true);
433   }
434 }
435 
getUsedRegs(const MCInst & Inst,BitVector & Regs) const436 void MCPlusBuilder::getUsedRegs(const MCInst &Inst, BitVector &Regs) const {
437   if (isPrefix(Inst) || isCFI(Inst))
438     return;
439 
440   const MCInstrDesc &InstInfo = Info->get(Inst.getOpcode());
441 
442   for (MCPhysReg ImplicitUse : InstInfo.implicit_uses())
443     Regs |= getAliases(ImplicitUse, /*OnlySmaller=*/true);
444 
445   for (unsigned I = 0, E = Inst.getNumOperands(); I != E; ++I) {
446     if (!Inst.getOperand(I).isReg())
447       continue;
448     Regs |= getAliases(Inst.getOperand(I).getReg(), /*OnlySmaller=*/true);
449   }
450 }
451 
getSrcRegs(const MCInst & Inst,BitVector & Regs) const452 void MCPlusBuilder::getSrcRegs(const MCInst &Inst, BitVector &Regs) const {
453   if (isPrefix(Inst) || isCFI(Inst))
454     return;
455 
456   if (isCall(Inst)) {
457     BitVector CallRegs = BitVector(Regs.size(), false);
458     getCalleeSavedRegs(CallRegs);
459     CallRegs.flip();
460     Regs |= CallRegs;
461     return;
462   }
463 
464   if (isReturn(Inst)) {
465     getDefaultLiveOut(Regs);
466     return;
467   }
468 
469   if (isRep(Inst))
470     getRepRegs(Regs);
471 
472   const MCInstrDesc &InstInfo = Info->get(Inst.getOpcode());
473 
474   for (MCPhysReg ImplicitUse : InstInfo.implicit_uses())
475     Regs |= getAliases(ImplicitUse, /*OnlySmaller=*/true);
476 
477   for (const MCOperand &Operand : useOperands(Inst))
478     if (Operand.isReg())
479       Regs |= getAliases(Operand.getReg(), /*OnlySmaller=*/true);
480 }
481 
hasDefOfPhysReg(const MCInst & MI,unsigned Reg) const482 bool MCPlusBuilder::hasDefOfPhysReg(const MCInst &MI, unsigned Reg) const {
483   const MCInstrDesc &InstInfo = Info->get(MI.getOpcode());
484   return InstInfo.hasDefOfPhysReg(MI, Reg, *RegInfo);
485 }
486 
hasUseOfPhysReg(const MCInst & MI,unsigned Reg) const487 bool MCPlusBuilder::hasUseOfPhysReg(const MCInst &MI, unsigned Reg) const {
488   const MCInstrDesc &InstInfo = Info->get(MI.getOpcode());
489   for (int I = InstInfo.NumDefs; I < InstInfo.NumOperands; ++I)
490     if (MI.getOperand(I).isReg() && MI.getOperand(I).getReg() &&
491         RegInfo->isSubRegisterEq(Reg, MI.getOperand(I).getReg()))
492       return true;
493   for (MCPhysReg ImplicitUse : InstInfo.implicit_uses()) {
494     if (ImplicitUse == Reg || RegInfo->isSubRegister(Reg, ImplicitUse))
495       return true;
496   }
497   return false;
498 }
499 
getAliases(MCPhysReg Reg,bool OnlySmaller) const500 const BitVector &MCPlusBuilder::getAliases(MCPhysReg Reg,
501                                            bool OnlySmaller) const {
502   if (OnlySmaller)
503     return SmallerAliasMap[Reg];
504   return AliasMap[Reg];
505 }
506 
initAliases()507 void MCPlusBuilder::initAliases() {
508   assert(AliasMap.size() == 0 && SmallerAliasMap.size() == 0);
509   // Build alias map
510   for (MCPhysReg I = 0, E = RegInfo->getNumRegs(); I != E; ++I) {
511     BitVector BV(RegInfo->getNumRegs(), false);
512     BV.set(I);
513     AliasMap.emplace_back(BV);
514     SmallerAliasMap.emplace_back(BV);
515   }
516 
517   // Cache all aliases for each register
518   for (MCPhysReg I = 1, E = RegInfo->getNumRegs(); I != E; ++I) {
519     for (MCRegAliasIterator AI(I, RegInfo, true); AI.isValid(); ++AI)
520       AliasMap[I].set(*AI);
521   }
522 
523   // Propagate smaller alias info upwards. Skip reg 0 (mapped to NoRegister)
524   for (MCPhysReg I = 1, E = RegInfo->getNumRegs(); I < E; ++I)
525     for (MCSubRegIterator SI(I, RegInfo); SI.isValid(); ++SI)
526       SmallerAliasMap[I] |= SmallerAliasMap[*SI];
527 
528   LLVM_DEBUG({
529     dbgs() << "Dumping reg alias table:\n";
530     for (MCPhysReg I = 0, E = RegInfo->getNumRegs(); I != E; ++I) {
531       dbgs() << "Reg " << I << ": ";
532       const BitVector &BV = AliasMap[I];
533       int Idx = BV.find_first();
534       while (Idx != -1) {
535         dbgs() << Idx << " ";
536         Idx = BV.find_next(Idx);
537       }
538       dbgs() << "\n";
539     }
540   });
541 }
542 
initSizeMap()543 void MCPlusBuilder::initSizeMap() {
544   SizeMap.resize(RegInfo->getNumRegs());
545   // Build size map
546   for (auto RC : RegInfo->regclasses())
547     for (MCPhysReg Reg : RC)
548       SizeMap[Reg] = RC.getSizeInBits() / 8;
549 }
550 
setOperandToSymbolRef(MCInst & Inst,int OpNum,const MCSymbol * Symbol,int64_t Addend,MCContext * Ctx,uint64_t RelType) const551 bool MCPlusBuilder::setOperandToSymbolRef(MCInst &Inst, int OpNum,
552                                           const MCSymbol *Symbol,
553                                           int64_t Addend, MCContext *Ctx,
554                                           uint64_t RelType) const {
555   MCOperand Operand;
556   if (!Addend) {
557     Operand = MCOperand::createExpr(getTargetExprFor(
558         Inst, MCSymbolRefExpr::create(Symbol, *Ctx), *Ctx, RelType));
559   } else {
560     Operand = MCOperand::createExpr(getTargetExprFor(
561         Inst,
562         MCBinaryExpr::createAdd(MCSymbolRefExpr::create(Symbol, *Ctx),
563                                 MCConstantExpr::create(Addend, *Ctx), *Ctx),
564         *Ctx, RelType));
565   }
566   Inst.getOperand(OpNum) = Operand;
567   return true;
568 }
569