xref: /aosp_15_r20/external/swiftshader/third_party/subzero/pnacl-llvm/NaClBitCodes.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1 //===- NaClBitcodeHeader.cpp ----------------------------------------------===//
2 //     PNaCl bitcode header reader.
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10 //
11 // Implementation of Bitcode abbrevations.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "llvm/Bitcode/NaCl/NaClBitCodes.h"
16 #include "llvm/Support/ErrorHandling.h"
17 #include "llvm/Support/raw_ostream.h"
18 
19 using namespace llvm;
20 
21 const bool NaClBitCodeAbbrevOp::HasValueArray[] = {
22     true,  // Literal
23     true,  // Fixed
24     true,  // VBR
25     false, // Array
26     false  // Char6
27 };
28 
29 const char *NaClBitCodeAbbrevOp::EncodingNameArray[] = {
30     "Literal", "Fixed", "VBR", "Array", "Char6"};
31 
NaClBitCodeAbbrevOp(Encoding E,uint64_t Data)32 NaClBitCodeAbbrevOp::NaClBitCodeAbbrevOp(Encoding E, uint64_t Data)
33     : Enc(E), Val(Data) {
34   if (isValid(E, Data))
35     return;
36   std::string Buffer;
37   raw_string_ostream StrBuf(Buffer);
38   StrBuf << "Invalid NaClBitCodeAbbrevOp(" << E << ", " << Data << ")";
39   report_fatal_error(StrBuf.str());
40 }
41 
isValid(Encoding E,uint64_t Val)42 bool NaClBitCodeAbbrevOp::isValid(Encoding E, uint64_t Val) {
43   switch (NaClBitCodeAbbrevOp::Encoding(E)) {
44   case Literal:
45     return true;
46   case Fixed:
47   case VBR:
48     return Val <= naclbitc::MaxAbbrevWidth;
49   case Char6:
50   case Array:
51     return Val == 0;
52   }
53   llvm_unreachable("unhandled abbreviation");
54 }
55 
Print(raw_ostream & Stream) const56 void NaClBitCodeAbbrevOp::Print(raw_ostream &Stream) const {
57   if (Enc == Literal) {
58     Stream << getValue();
59     return;
60   }
61   Stream << getEncodingName(Enc);
62   if (!hasValue())
63     return;
64   Stream << "(" << Val << ")";
65 }
66 
PrintExpression(raw_ostream & Stream,const NaClBitCodeAbbrev * Abbrev,unsigned & Index)67 static void PrintExpression(raw_ostream &Stream,
68                             const NaClBitCodeAbbrev *Abbrev, unsigned &Index) {
69   // Bail out early, in case we are incrementally building the
70   // expression and the argument is not available yet.
71   if (Index >= Abbrev->getNumOperandInfos())
72     return;
73 
74   const NaClBitCodeAbbrevOp &Op = Abbrev->getOperandInfo(Index);
75   Op.Print(Stream);
76   if (unsigned NumArgs = Op.NumArguments()) {
77     Stream << "(";
78     for (unsigned i = 0; i < NumArgs; ++i) {
79       ++Index;
80       if (i > 0)
81         Stream << ",";
82       PrintExpression(Stream, Abbrev, Index);
83     }
84     Stream << ")";
85   }
86 }
87 
Print(raw_ostream & Stream,bool AddNewLine) const88 void NaClBitCodeAbbrev::Print(raw_ostream &Stream, bool AddNewLine) const {
89   Stream << "[";
90   for (unsigned i = 0; i < getNumOperandInfos(); ++i) {
91     if (i > 0)
92       Stream << ", ";
93     PrintExpression(Stream, this, i);
94   }
95   Stream << "]";
96   if (AddNewLine)
97     Stream << "\n";
98 }
99 
Simplify() const100 NaClBitCodeAbbrev *NaClBitCodeAbbrev::Simplify() const {
101   NaClBitCodeAbbrev *Abbrev = new NaClBitCodeAbbrev();
102   for (unsigned i = 0; i < OperandList.size(); ++i) {
103     const NaClBitCodeAbbrevOp &Op = OperandList[i];
104     // Simplify if possible.  Currently, the only simplification known
105     // is to remove unnecessary operands appearing immediately before an
106     // array operator. That is, apply the simplification:
107     //    Op Array(Op) -> Array(Op)
108     assert(!Op.isArrayOp() || i == OperandList.size() - 2);
109     while (Op.isArrayOp() && !Abbrev->OperandList.empty() &&
110            Abbrev->OperandList.back() == OperandList[i + 1]) {
111       Abbrev->OperandList.pop_back();
112     }
113     Abbrev->OperandList.push_back(Op);
114   }
115   return Abbrev;
116 }
117 
isValid() const118 bool NaClBitCodeAbbrev::isValid() const {
119   // Verify that an array op appears can only appear if it is the
120   // second to last element.
121   unsigned NumOperands = getNumOperandInfos();
122   if (NumOperands == 0)
123     return false;
124   for (unsigned i = 0; i < NumOperands; ++i) {
125     const NaClBitCodeAbbrevOp &Op = getOperandInfo(i);
126     if (Op.isArrayOp() && i + 2 != NumOperands)
127       // Note: Unlike LLVM bitcode, we allow literals in arrays!
128       return false;
129   }
130   return true;
131 }
132