/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/IR/ProfileSummary.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //=-- Profilesummary.cpp - Profile summary support --------------------------=// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This file contains support for converting profile summary data from/to |
11 | | // metadata. |
12 | | // |
13 | | //===----------------------------------------------------------------------===// |
14 | | |
15 | | #include "llvm/IR/ProfileSummary.h" |
16 | | #include "llvm/IR/Attributes.h" |
17 | | #include "llvm/IR/Constants.h" |
18 | | #include "llvm/IR/Function.h" |
19 | | #include "llvm/IR/Metadata.h" |
20 | | #include "llvm/IR/Type.h" |
21 | | #include "llvm/Support/Casting.h" |
22 | | |
23 | | using namespace llvm; |
24 | | |
25 | | const char *ProfileSummary::KindStr[2] = {"InstrProf", "SampleProfile"}; |
26 | | |
27 | | // Return an MDTuple with two elements. The first element is a string Key and |
28 | | // the second is a uint64_t Value. |
29 | | static Metadata *getKeyValMD(LLVMContext &Context, const char *Key, |
30 | 786 | uint64_t Val) { |
31 | 786 | Type *Int64Ty = Type::getInt64Ty(Context); |
32 | 786 | Metadata *Ops[2] = {MDString::get(Context, Key), |
33 | 786 | ConstantAsMetadata::get(ConstantInt::get(Int64Ty, Val))}; |
34 | 786 | return MDTuple::get(Context, Ops); |
35 | 786 | } |
36 | | |
37 | | // Return an MDTuple with two elements. The first element is a string Key and |
38 | | // the second is a string Value. |
39 | | static Metadata *getKeyValMD(LLVMContext &Context, const char *Key, |
40 | 131 | const char *Val) { |
41 | 131 | Metadata *Ops[2] = {MDString::get(Context, Key), MDString::get(Context, Val)}; |
42 | 131 | return MDTuple::get(Context, Ops); |
43 | 131 | } |
44 | | |
45 | | // This returns an MDTuple representing the detiled summary. The tuple has two |
46 | | // elements: a string "DetailedSummary" and an MDTuple representing the value |
47 | | // of the detailed summary. Each element of this tuple is again an MDTuple whose |
48 | | // elements are the (Cutoff, MinCount, NumCounts) triplet of the |
49 | | // DetailedSummaryEntry. |
50 | 131 | Metadata *ProfileSummary::getDetailedSummaryMD(LLVMContext &Context) { |
51 | 131 | std::vector<Metadata *> Entries; |
52 | 131 | Type *Int32Ty = Type::getInt32Ty(Context); |
53 | 131 | Type *Int64Ty = Type::getInt64Ty(Context); |
54 | 2.35k | for (auto &Entry : DetailedSummary) { |
55 | 2.35k | Metadata *EntryMD[3] = { |
56 | 2.35k | ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Entry.Cutoff)), |
57 | 2.35k | ConstantAsMetadata::get(ConstantInt::get(Int64Ty, Entry.MinCount)), |
58 | 2.35k | ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Entry.NumCounts))}; |
59 | 2.35k | Entries.push_back(MDTuple::get(Context, EntryMD)); |
60 | 2.35k | } |
61 | 131 | Metadata *Ops[2] = {MDString::get(Context, "DetailedSummary"), |
62 | 131 | MDTuple::get(Context, Entries)}; |
63 | 131 | return MDTuple::get(Context, Ops); |
64 | 131 | } |
65 | | |
66 | | // This returns an MDTuple representing this ProfileSummary object. The first |
67 | | // entry of this tuple is another MDTuple of two elements: a string |
68 | | // "ProfileFormat" and a string representing the format ("InstrProf" or |
69 | | // "SampleProfile"). The rest of the elements of the outer MDTuple are specific |
70 | | // to the kind of profile summary as returned by getFormatSpecificMD. |
71 | 131 | Metadata *ProfileSummary::getMD(LLVMContext &Context) { |
72 | 131 | std::vector<Metadata *> Components; |
73 | 131 | Components.push_back(getKeyValMD(Context, "ProfileFormat", KindStr[PSK])); |
74 | 131 | |
75 | 131 | Components.push_back(getKeyValMD(Context, "TotalCount", getTotalCount())); |
76 | 131 | Components.push_back(getKeyValMD(Context, "MaxCount", getMaxCount())); |
77 | 131 | Components.push_back( |
78 | 131 | getKeyValMD(Context, "MaxInternalCount", getMaxInternalCount())); |
79 | 131 | Components.push_back( |
80 | 131 | getKeyValMD(Context, "MaxFunctionCount", getMaxFunctionCount())); |
81 | 131 | Components.push_back(getKeyValMD(Context, "NumCounts", getNumCounts())); |
82 | 131 | Components.push_back(getKeyValMD(Context, "NumFunctions", getNumFunctions())); |
83 | 131 | Components.push_back(getDetailedSummaryMD(Context)); |
84 | 131 | return MDTuple::get(Context, Components); |
85 | 131 | } |
86 | | |
87 | | // Parse an MDTuple representing (Key, Val) pair. |
88 | 318 | static bool getVal(MDTuple *MD, const char *Key, uint64_t &Val) { |
89 | 318 | if (!MD) |
90 | 0 | return false; |
91 | 318 | if (318 MD->getNumOperands() != 2318 ) |
92 | 0 | return false; |
93 | 318 | MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0)); |
94 | 318 | ConstantAsMetadata *ValMD = dyn_cast<ConstantAsMetadata>(MD->getOperand(1)); |
95 | 318 | if (!KeyMD || 318 !ValMD318 ) |
96 | 0 | return false; |
97 | 318 | if (318 !KeyMD->getString().equals(Key)318 ) |
98 | 0 | return false; |
99 | 318 | Val = cast<ConstantInt>(ValMD->getValue())->getZExtValue(); |
100 | 318 | return true; |
101 | 318 | } |
102 | | |
103 | | // Check if an MDTuple represents a (Key, Val) pair. |
104 | 76 | static bool isKeyValuePair(MDTuple *MD, const char *Key, const char *Val) { |
105 | 76 | if (!MD || 76 MD->getNumOperands() != 276 ) |
106 | 0 | return false; |
107 | 76 | MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0)); |
108 | 76 | MDString *ValMD = dyn_cast<MDString>(MD->getOperand(1)); |
109 | 76 | if (!KeyMD || 76 !ValMD76 ) |
110 | 0 | return false; |
111 | 76 | if (76 !KeyMD->getString().equals(Key) || 76 !ValMD->getString().equals(Val)76 ) |
112 | 23 | return false; |
113 | 53 | return true; |
114 | 53 | } |
115 | | |
116 | | // Parse an MDTuple representing detailed summary. |
117 | 53 | static bool getSummaryFromMD(MDTuple *MD, SummaryEntryVector &Summary) { |
118 | 53 | if (!MD || 53 MD->getNumOperands() != 253 ) |
119 | 0 | return false; |
120 | 53 | MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0)); |
121 | 53 | if (!KeyMD || 53 !KeyMD->getString().equals("DetailedSummary")53 ) |
122 | 0 | return false; |
123 | 53 | MDTuple *EntriesMD = dyn_cast<MDTuple>(MD->getOperand(1)); |
124 | 53 | if (!EntriesMD) |
125 | 0 | return false; |
126 | 53 | for (auto &&MDOp : EntriesMD->operands()) 53 { |
127 | 609 | MDTuple *EntryMD = dyn_cast<MDTuple>(MDOp); |
128 | 609 | if (!EntryMD || 609 EntryMD->getNumOperands() != 3609 ) |
129 | 0 | return false; |
130 | 609 | ConstantAsMetadata *Op0 = |
131 | 609 | dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(0)); |
132 | 609 | ConstantAsMetadata *Op1 = |
133 | 609 | dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(1)); |
134 | 609 | ConstantAsMetadata *Op2 = |
135 | 609 | dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(2)); |
136 | 609 | |
137 | 609 | if (!Op0 || 609 !Op1609 || !Op2609 ) |
138 | 0 | return false; |
139 | 609 | Summary.emplace_back(cast<ConstantInt>(Op0->getValue())->getZExtValue(), |
140 | 609 | cast<ConstantInt>(Op1->getValue())->getZExtValue(), |
141 | 609 | cast<ConstantInt>(Op2->getValue())->getZExtValue()); |
142 | 609 | } |
143 | 53 | return true; |
144 | 53 | } |
145 | | |
146 | 53 | ProfileSummary *ProfileSummary::getFromMD(Metadata *MD) { |
147 | 53 | if (!MD) |
148 | 0 | return nullptr; |
149 | 53 | if (53 !isa<MDTuple>(MD)53 ) |
150 | 0 | return nullptr; |
151 | 53 | MDTuple *Tuple = cast<MDTuple>(MD); |
152 | 53 | if (Tuple->getNumOperands() != 8) |
153 | 0 | return nullptr; |
154 | 53 | |
155 | 53 | auto &FormatMD = Tuple->getOperand(0); |
156 | 53 | ProfileSummary::Kind SummaryKind; |
157 | 53 | if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat", |
158 | 53 | "SampleProfile")) |
159 | 30 | SummaryKind = PSK_Sample; |
160 | 23 | else if (23 isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat", |
161 | 23 | "InstrProf")) |
162 | 23 | SummaryKind = PSK_Instr; |
163 | 23 | else |
164 | 0 | return nullptr; |
165 | 53 | |
166 | 53 | uint64_t NumCounts, TotalCount, NumFunctions, MaxFunctionCount, MaxCount, |
167 | 53 | MaxInternalCount; |
168 | 53 | if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(1)), "TotalCount", |
169 | 53 | TotalCount)) |
170 | 0 | return nullptr; |
171 | 53 | if (53 !getVal(dyn_cast<MDTuple>(Tuple->getOperand(2)), "MaxCount", MaxCount)53 ) |
172 | 0 | return nullptr; |
173 | 53 | if (53 !getVal(dyn_cast<MDTuple>(Tuple->getOperand(3)), "MaxInternalCount", |
174 | 53 | MaxInternalCount)) |
175 | 0 | return nullptr; |
176 | 53 | if (53 !getVal(dyn_cast<MDTuple>(Tuple->getOperand(4)), "MaxFunctionCount", |
177 | 53 | MaxFunctionCount)) |
178 | 0 | return nullptr; |
179 | 53 | if (53 !getVal(dyn_cast<MDTuple>(Tuple->getOperand(5)), "NumCounts", NumCounts)53 ) |
180 | 0 | return nullptr; |
181 | 53 | if (53 !getVal(dyn_cast<MDTuple>(Tuple->getOperand(6)), "NumFunctions", |
182 | 53 | NumFunctions)) |
183 | 0 | return nullptr; |
184 | 53 | |
185 | 53 | SummaryEntryVector Summary; |
186 | 53 | if (!getSummaryFromMD(dyn_cast<MDTuple>(Tuple->getOperand(7)), Summary)) |
187 | 0 | return nullptr; |
188 | 53 | return new ProfileSummary(SummaryKind, Summary, TotalCount, MaxCount, |
189 | 53 | MaxInternalCount, MaxFunctionCount, NumCounts, |
190 | 53 | NumFunctions); |
191 | 53 | } |