xref: /minix3/minix/llvm/passes/magic/support/BitFieldAggregation.cpp (revision 3e457fe321c6af238c180a2b4a0f010f8b4f8c31)
1 #include <magic/support/BitFieldAggregation.h>
2 
3 using namespace llvm;
4 
5 namespace llvm {
6 
7 #define DEBUG_BFA           0
8 
9 #define BitFieldAggregation_assert_or_return(R,RV,T,ET,X) do {              \
10         if(!(X)) {                        \
11             if(R) return RV;              \
12             errs() << "Assertion failed, dumping types...\n"; \
13             errs() << TypeUtil::getDescription(T, ET); \
14         }                                 \
15         assert(X);                        \
16     } while(0)
17 
18 //===----------------------------------------------------------------------===//
19 // Constructors, destructor, and operators
20 //===----------------------------------------------------------------------===//
21 
BitFieldAggregation(TYPECONST Type * type,std::vector<EDIType> EDITypes,unsigned typeIndex,unsigned EDITypeIndex,std::vector<DIDerivedType> members,unsigned counter)22 BitFieldAggregation::BitFieldAggregation(TYPECONST Type* type, std::vector<EDIType> EDITypes, unsigned typeIndex, unsigned EDITypeIndex, std::vector<DIDerivedType> members, unsigned counter) {
23     init(type, EDITypes, typeIndex, EDITypeIndex, members, counter);
24 }
25 
BitFieldAggregation()26 BitFieldAggregation::BitFieldAggregation() {
27     type = NULL;
28     typeIndex = 0;
29     EDITypeIndex = 0;
30     name = "";
31 }
32 
init(TYPECONST Type * type,std::vector<EDIType> EDITypes,unsigned typeIndex,unsigned EDITypeIndex,std::vector<DIDerivedType> members,unsigned counter)33 void BitFieldAggregation::init(TYPECONST Type* type, std::vector<EDIType> EDITypes, unsigned typeIndex, unsigned EDITypeIndex, std::vector<DIDerivedType> members, unsigned counter) {
34     assert(members.size() == EDITypes.size());
35     assert(typeIndex <= EDITypeIndex);
36     size = members.size();
37     assert(size > 0);
38 
39     this->type = type;
40     this->EDITypes = EDITypes;
41     this->typeIndex = typeIndex;
42     this->EDITypeIndex = EDITypeIndex;
43     this->members = members;
44     raw_string_ostream ostream(name);
45     ostream << bfaNamePrefix << counter;
46     ostream.flush();
47 }
48 
49 //===----------------------------------------------------------------------===//
50 // Getters
51 //===----------------------------------------------------------------------===//
52 
getDescription() const53 const std::string BitFieldAggregation::getDescription() const {
54     std::string string;
55     raw_string_ostream ostream(string);
56     ostream << "[\nname = " << name << "\nmembers = ";
57     for(unsigned i=0;i<size;i++) {
58         ostream << (i==0 ? "" : ", ") << members[i].getName();
59     }
60     ostream << "\ntype = \n" << TypeUtil::getDescription(getType());
61     std::vector<EDIType> EDITypes = getEDITypes();
62     for(unsigned i=0;i<EDITypes.size();i++) {
63         ostream << "\nEDIType" << i << " =\n" << TypeUtil::getDescription(&EDITypes[i]);
64     }
65     ostream << "\n]";
66     ostream.flush();
67     return string;
68 }
69 
70 //===----------------------------------------------------------------------===//
71 // Public static methods
72 //===----------------------------------------------------------------------===//
73 
getBitFieldAggregations(TYPECONST Type * type,const EDIType * aEDIType,std::vector<BitFieldAggregation> & bfas,bool returnOnError)74 bool BitFieldAggregation::getBitFieldAggregations(TYPECONST Type *type, const EDIType *aEDIType, std::vector<BitFieldAggregation> &bfas, bool returnOnError) {
75     std::vector<BitFieldAggregation> emptyBfas;
76     if(!hasBitFields(type, aEDIType)) {
77         return true;
78     }
79     unsigned typeIndex = 0;
80     unsigned EDITypeIndex = 0;
81     unsigned typeContainedTypes = type->getNumContainedTypes();
82     unsigned aEDITypeContainedTypes = aEDIType->getNumContainedTypes();
83     unsigned counter = 1;
84     const EDIType privateEDIType(*aEDIType);
85     aEDIType = &privateEDIType;
86     while(typeIndex < typeContainedTypes) {
87         TYPECONST Type *containedType = type->getContainedType(typeIndex);
88         if(EDITypeIndex >= aEDITypeContainedTypes && typeIndex == typeContainedTypes-1 && TypeUtil::isPaddedType(type)) {
89             break;
90         }
91         BitFieldAggregation_assert_or_return(returnOnError, false, type, aEDIType, EDITypeIndex < aEDITypeContainedTypes);
92         const EDIType containedEDIType = aEDIType->getContainedType(EDITypeIndex);
93         unsigned typeBits = TypeUtil::typeToBits(containedType);
94         if(typeBits > 0 && containedEDIType.isIntegerTy()) {
95             unsigned EDITypeBits = aEDIType->getMember(EDITypeIndex).getSizeInBits();
96             assert(typeBits >= EDITypeBits);
97             if(typeBits > EDITypeBits) {
98                 unsigned lastTypeIndex = typeIndex;
99                 unsigned lastEDITypeIndex = EDITypeIndex;
100                 while(lastEDITypeIndex+1 < aEDITypeContainedTypes && isBitField(type, aEDIType, lastEDITypeIndex+1)) { // grab all the bitfields following the first one found
101                     lastEDITypeIndex++;
102                     EDITypeBits += aEDIType->getMember(lastEDITypeIndex).getSizeInBits();
103                 }
104                 while(lastTypeIndex+1 < typeContainedTypes && EDITypeBits > typeBits) { // grab all the necessary fields to cover all the bits found in the bitfields
105                     lastTypeIndex++;
106                     typeBits += TypeUtil::typeToBits(type->getContainedType(lastTypeIndex));
107                 }
108                 BitFieldAggregation *bfa = BitFieldAggregation::getBitFieldAggregation(type, aEDIType, returnOnError, typeIndex, EDITypeIndex, lastTypeIndex, lastEDITypeIndex, counter++);
109                 BitFieldAggregation_assert_or_return(returnOnError, false, type, aEDIType, bfa != NULL);
110                 if(bfa->getSize() > 1) {
111                     //we don't care about single-element aggregates
112                     bfas.push_back(*bfa);
113                 }
114                 typeIndex++;
115                 EDITypeIndex += bfa->getSize();
116                 continue;
117             }
118         }
119         typeIndex++;
120         EDITypeIndex++;
121     }
122     return true;
123 }
124 
getBitFieldAggregation(TYPECONST Type * type,const EDIType * aEDIType,bool returnOnError,unsigned typeIndex,unsigned EDITypeIndex,unsigned lastTypeIndex,unsigned lastEDITypeIndex,unsigned counter)125 BitFieldAggregation *BitFieldAggregation::getBitFieldAggregation(TYPECONST Type *type, const EDIType *aEDIType, bool returnOnError, unsigned typeIndex, unsigned EDITypeIndex, unsigned lastTypeIndex, unsigned lastEDITypeIndex, unsigned counter) {
126     static BitFieldAggregation bfa;
127     TYPECONST Type *containedType = type->getContainedType(typeIndex);
128     unsigned typeBits = TypeUtil::typeToBits(containedType);
129     assert(typeBits > 0);
130     unsigned nextTypeBits = 0;
131     if (typeIndex < lastTypeIndex) {
132         nextTypeBits = TypeUtil::typeToBits(type->getContainedType(typeIndex+1));
133     }
134     const int maxNumMembers = (lastEDITypeIndex - EDITypeIndex) - (lastTypeIndex - typeIndex) + 1;
135     unsigned index = EDITypeIndex;
136     std::vector<DIDerivedType> members;
137     std::vector<EDIType> containedEDITypes;
138 
139     BitFieldAggregation_assert_or_return(returnOnError, NULL, type, aEDIType, maxNumMembers > 0);
140 #if DEBUG_BFA
141     BitFieldAggregationErr("getBitFieldAggregation(): typeIndex = " << typeIndex << ", EDITypeIndex = " << EDITypeIndex << ", maxNumMembers = " << maxNumMembers);
142     BitFieldAggregationErr("getBitFieldAggregation(): lastTypeIndex = " << lastTypeIndex << ", lastEDITypeIndex = " << lastEDITypeIndex);
143     BitFieldAggregationErr("getBitFieldAggregation(): " << TypeUtil::getDescription(type) << " VS " << TypeUtil::getDescription(aEDIType));
144 #endif
145     while(index <= lastEDITypeIndex && members.size() < (unsigned)maxNumMembers) {
146         const EDIType containedEDIType = aEDIType->getContainedType(index);
147 #if DEBUG_BFA
148         BitFieldAggregationErr("Examining type " << TypeUtil::getDescription(&containedEDIType));
149 #endif
150         BitFieldAggregation_assert_or_return(returnOnError, NULL, type, aEDIType, containedEDIType.isIntegerTy());
151         DIDerivedType member = aEDIType->getMember(index);
152         unsigned EDITypeBits = member.getSizeInBits();
153 #if DEBUG_BFA
154         BitFieldAggregationErr("Type bits = " << typeBits << ", next type bits = " << nextTypeBits << ", index = " << index);
155         BitFieldAggregationErr("This is member " << member.getName() << " with bits " << EDITypeBits);
156 #endif
157         if((index > EDITypeIndex && EDITypeBits == nextTypeBits) || EDITypeBits > typeBits) {
158             break;
159         }
160         typeBits -= EDITypeBits;
161         members.push_back(member);
162         containedEDITypes.push_back(containedEDIType);
163         index++;
164     }
165     bfa.init(containedType, containedEDITypes, typeIndex, EDITypeIndex, members, counter);
166     return &bfa;
167 }
168 
169 std::string BitFieldAggregation::bfaNamePrefix = BFA_NAME_PREFIX;
170 
171 }
172