etc/services - sync with NetBSD-8
[minix.git] / minix / llvm / passes / magic / support / BitFieldAggregation.cpp
blobc107d93af6097c9f8cbec54acc8f539a13d4dd2f
1 #include <magic/support/BitFieldAggregation.h>
3 using namespace llvm;
5 namespace llvm {
7 #define DEBUG_BFA 0
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)
18 //===----------------------------------------------------------------------===//
19 // Constructors, destructor, and operators
20 //===----------------------------------------------------------------------===//
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);
26 BitFieldAggregation::BitFieldAggregation() {
27 type = NULL;
28 typeIndex = 0;
29 EDITypeIndex = 0;
30 name = "";
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);
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();
49 //===----------------------------------------------------------------------===//
50 // Getters
51 //===----------------------------------------------------------------------===//
53 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();
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]);
65 ostream << "\n]";
66 ostream.flush();
67 return string;
70 //===----------------------------------------------------------------------===//
71 // Public static methods
72 //===----------------------------------------------------------------------===//
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;
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;
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();
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));
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);
114 typeIndex++;
115 EDITypeIndex += bfa->getSize();
116 continue;
119 typeIndex++;
120 EDITypeIndex++;
122 return true;
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));
134 const int maxNumMembers = (lastEDITypeIndex - EDITypeIndex) - (lastTypeIndex - typeIndex) + 1;
135 unsigned index = EDITypeIndex;
136 std::vector<DIDerivedType> members;
137 std::vector<EDIType> containedEDITypes;
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;
160 typeBits -= EDITypeBits;
161 members.push_back(member);
162 containedEDITypes.push_back(containedEDIType);
163 index++;
165 bfa.init(containedType, containedEDITypes, typeIndex, EDITypeIndex, members, counter);
166 return &bfa;
169 std::string BitFieldAggregation::bfaNamePrefix = BFA_NAME_PREFIX;