File: | lib/Target/TargetRecip.cpp |
Location: | line 161, column 51 |
Description: | Assigned value is garbage or undefined |
1 | //===-------------------------- TargetRecip.cpp ---------------------------===// | |||
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 class is used to customize machine-specific reciprocal estimate code | |||
11 | // generation in a target-independent way. | |||
12 | // If a target does not support operations in this specification, then code | |||
13 | // generation will default to using supported operations. | |||
14 | // | |||
15 | //===----------------------------------------------------------------------===// | |||
16 | ||||
17 | #include "llvm/Target/TargetRecip.h" | |||
18 | #include "llvm/ADT/STLExtras.h" | |||
19 | #include "llvm/ADT/StringRef.h" | |||
20 | #include "llvm/Support/ErrorHandling.h" | |||
21 | ||||
22 | using namespace llvm; | |||
23 | ||||
24 | // These are the names of the individual reciprocal operations. These are | |||
25 | // the key strings for queries and command-line inputs. | |||
26 | // In addition, the command-line interface recognizes the global parameters | |||
27 | // "all", "none", and "default". | |||
28 | static const char *const RecipOps[] = { | |||
29 | "divd", | |||
30 | "divf", | |||
31 | "vec-divd", | |||
32 | "vec-divf", | |||
33 | "sqrtd", | |||
34 | "sqrtf", | |||
35 | "vec-sqrtd", | |||
36 | "vec-sqrtf", | |||
37 | }; | |||
38 | ||||
39 | // The uninitialized state is needed for the enabled settings and refinement | |||
40 | // steps because custom settings may arrive via the command-line before target | |||
41 | // defaults are set. | |||
42 | TargetRecip::TargetRecip() { | |||
43 | unsigned NumStrings = llvm::array_lengthof(RecipOps); | |||
44 | for (unsigned i = 0; i < NumStrings; ++i) | |||
45 | RecipMap.insert(std::make_pair(RecipOps[i], RecipParams())); | |||
46 | } | |||
47 | ||||
48 | static bool parseRefinementStep(StringRef In, size_t &Position, | |||
49 | uint8_t &Value) { | |||
50 | const char RefStepToken = ':'; | |||
51 | Position = In.find(RefStepToken); | |||
52 | if (Position == StringRef::npos) | |||
53 | return false; | |||
54 | ||||
55 | StringRef RefStepString = In.substr(Position + 1); | |||
56 | // Allow exactly one numeric character for the additional refinement | |||
57 | // step parameter. | |||
58 | if (RefStepString.size() == 1) { | |||
59 | char RefStepChar = RefStepString[0]; | |||
60 | if (RefStepChar >= '0' && RefStepChar <= '9') { | |||
61 | Value = RefStepChar - '0'; | |||
62 | return true; | |||
63 | } | |||
64 | } | |||
65 | report_fatal_error("Invalid refinement step for -recip."); | |||
66 | } | |||
67 | ||||
68 | bool TargetRecip::parseGlobalParams(const std::string &Arg) { | |||
69 | StringRef ArgSub = Arg; | |||
70 | ||||
71 | // Look for an optional setting of the number of refinement steps needed | |||
72 | // for this type of reciprocal operation. | |||
73 | size_t RefPos; | |||
74 | uint8_t RefSteps; | |||
75 | StringRef RefStepString; | |||
76 | if (parseRefinementStep(ArgSub, RefPos, RefSteps)) { | |||
77 | // Split the string for further processing. | |||
78 | RefStepString = ArgSub.substr(RefPos + 1); | |||
79 | ArgSub = ArgSub.substr(0, RefPos); | |||
80 | } | |||
81 | bool Enable; | |||
82 | bool UseDefaults; | |||
83 | if (ArgSub == "all") { | |||
84 | UseDefaults = false; | |||
85 | Enable = true; | |||
86 | } else if (ArgSub == "none") { | |||
87 | UseDefaults = false; | |||
88 | Enable = false; | |||
89 | } else if (ArgSub == "default") { | |||
90 | UseDefaults = true; | |||
91 | } else { | |||
92 | // Any other string is invalid or an individual setting. | |||
93 | return false; | |||
94 | } | |||
95 | ||||
96 | // All enable values will be initialized to target defaults if 'default' was | |||
97 | // specified. | |||
98 | if (!UseDefaults) | |||
99 | for (auto &KV : RecipMap) | |||
100 | KV.second.Enabled = Enable; | |||
101 | ||||
102 | // Custom refinement count was specified with all, none, or default. | |||
103 | if (!RefStepString.empty()) | |||
104 | for (auto &KV : RecipMap) | |||
105 | KV.second.RefinementSteps = RefSteps; | |||
106 | ||||
107 | return true; | |||
108 | } | |||
109 | ||||
110 | void TargetRecip::parseIndividualParams(const std::vector<std::string> &Args) { | |||
111 | static const char DisabledPrefix = '!'; | |||
112 | unsigned NumArgs = Args.size(); | |||
113 | ||||
114 | for (unsigned i = 0; i != NumArgs; ++i) { | |||
115 | StringRef Val = Args[i]; | |||
116 | ||||
117 | bool IsDisabled = Val[0] == DisabledPrefix; | |||
118 | // Ignore the disablement token for string matching. | |||
119 | if (IsDisabled) | |||
120 | Val = Val.substr(1); | |||
121 | ||||
122 | size_t RefPos; | |||
123 | uint8_t RefSteps; | |||
124 | StringRef RefStepString; | |||
125 | if (parseRefinementStep(Val, RefPos, RefSteps)) { | |||
126 | // Split the string for further processing. | |||
127 | RefStepString = Val.substr(RefPos + 1); | |||
128 | Val = Val.substr(0, RefPos); | |||
129 | } | |||
130 | ||||
131 | RecipIter Iter = RecipMap.find(Val); | |||
132 | if (Iter == RecipMap.end()) { | |||
133 | // Try again specifying float suffix. | |||
134 | Iter = RecipMap.find(Val.str() + 'f'); | |||
135 | if (Iter == RecipMap.end()) { | |||
136 | Iter = RecipMap.find(Val.str() + 'd'); | |||
137 | assert(Iter == RecipMap.end() && "Float entry missing from map")((Iter == RecipMap.end() && "Float entry missing from map" ) ? static_cast<void> (0) : __assert_fail ("Iter == RecipMap.end() && \"Float entry missing from map\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn271203/lib/Target/TargetRecip.cpp" , 137, __PRETTY_FUNCTION__)); | |||
138 | report_fatal_error("Invalid option for -recip."); | |||
139 | } | |||
140 | ||||
141 | // The option was specified without a float or double suffix. | |||
142 | if (RecipMap[Val.str() + 'd'].Enabled != Uninitialized) { | |||
143 | // Make sure that the double entry was not already specified. | |||
144 | // The float entry will be checked below. | |||
145 | report_fatal_error("Duplicate option for -recip."); | |||
146 | } | |||
147 | } | |||
148 | ||||
149 | if (Iter->second.Enabled != Uninitialized) | |||
150 | report_fatal_error("Duplicate option for -recip."); | |||
151 | ||||
152 | // Mark the matched option as found. Do not allow duplicate specifiers. | |||
153 | Iter->second.Enabled = !IsDisabled; | |||
154 | if (!RefStepString.empty()) | |||
155 | Iter->second.RefinementSteps = RefSteps; | |||
156 | ||||
157 | // If the precision was not specified, the double entry is also initialized. | |||
158 | if (Val.back() != 'f' && Val.back() != 'd') { | |||
159 | RecipMap[Val.str() + 'd'].Enabled = !IsDisabled; | |||
160 | if (!RefStepString.empty()) | |||
161 | RecipMap[Val.str() + 'd'].RefinementSteps = RefSteps; | |||
| ||||
162 | } | |||
163 | } | |||
164 | } | |||
165 | ||||
166 | TargetRecip::TargetRecip(const std::vector<std::string> &Args) : | |||
167 | TargetRecip() { | |||
168 | unsigned NumArgs = Args.size(); | |||
169 | ||||
170 | // Check if "all", "default", or "none" was specified. | |||
171 | if (NumArgs == 1 && parseGlobalParams(Args[0])) | |||
| ||||
172 | return; | |||
173 | ||||
174 | parseIndividualParams(Args); | |||
175 | } | |||
176 | ||||
177 | bool TargetRecip::isEnabled(StringRef Key) const { | |||
178 | ConstRecipIter Iter = RecipMap.find(Key); | |||
179 | assert(Iter != RecipMap.end() && "Unknown name for reciprocal map")((Iter != RecipMap.end() && "Unknown name for reciprocal map" ) ? static_cast<void> (0) : __assert_fail ("Iter != RecipMap.end() && \"Unknown name for reciprocal map\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn271203/lib/Target/TargetRecip.cpp" , 179, __PRETTY_FUNCTION__)); | |||
180 | assert(Iter->second.Enabled != Uninitialized &&((Iter->second.Enabled != Uninitialized && "Enablement setting was not initialized" ) ? static_cast<void> (0) : __assert_fail ("Iter->second.Enabled != Uninitialized && \"Enablement setting was not initialized\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn271203/lib/Target/TargetRecip.cpp" , 181, __PRETTY_FUNCTION__)) | |||
181 | "Enablement setting was not initialized")((Iter->second.Enabled != Uninitialized && "Enablement setting was not initialized" ) ? static_cast<void> (0) : __assert_fail ("Iter->second.Enabled != Uninitialized && \"Enablement setting was not initialized\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn271203/lib/Target/TargetRecip.cpp" , 181, __PRETTY_FUNCTION__)); | |||
182 | return Iter->second.Enabled; | |||
183 | } | |||
184 | ||||
185 | unsigned TargetRecip::getRefinementSteps(StringRef Key) const { | |||
186 | ConstRecipIter Iter = RecipMap.find(Key); | |||
187 | assert(Iter != RecipMap.end() && "Unknown name for reciprocal map")((Iter != RecipMap.end() && "Unknown name for reciprocal map" ) ? static_cast<void> (0) : __assert_fail ("Iter != RecipMap.end() && \"Unknown name for reciprocal map\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn271203/lib/Target/TargetRecip.cpp" , 187, __PRETTY_FUNCTION__)); | |||
188 | assert(Iter->second.RefinementSteps != Uninitialized &&((Iter->second.RefinementSteps != Uninitialized && "Refinement step setting was not initialized") ? static_cast <void> (0) : __assert_fail ("Iter->second.RefinementSteps != Uninitialized && \"Refinement step setting was not initialized\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn271203/lib/Target/TargetRecip.cpp" , 189, __PRETTY_FUNCTION__)) | |||
189 | "Refinement step setting was not initialized")((Iter->second.RefinementSteps != Uninitialized && "Refinement step setting was not initialized") ? static_cast <void> (0) : __assert_fail ("Iter->second.RefinementSteps != Uninitialized && \"Refinement step setting was not initialized\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn271203/lib/Target/TargetRecip.cpp" , 189, __PRETTY_FUNCTION__)); | |||
190 | return Iter->second.RefinementSteps; | |||
191 | } | |||
192 | ||||
193 | /// Custom settings (previously initialized values) override target defaults. | |||
194 | void TargetRecip::setDefaults(StringRef Key, bool Enable, | |||
195 | unsigned RefSteps) { | |||
196 | if (Key == "all") { | |||
197 | for (auto &KV : RecipMap) { | |||
198 | RecipParams &RP = KV.second; | |||
199 | if (RP.Enabled == Uninitialized) | |||
200 | RP.Enabled = Enable; | |||
201 | if (RP.RefinementSteps == Uninitialized) | |||
202 | RP.RefinementSteps = RefSteps; | |||
203 | } | |||
204 | } else { | |||
205 | RecipParams &RP = RecipMap[Key]; | |||
206 | if (RP.Enabled == Uninitialized) | |||
207 | RP.Enabled = Enable; | |||
208 | if (RP.RefinementSteps == Uninitialized) | |||
209 | RP.RefinementSteps = RefSteps; | |||
210 | } | |||
211 | } | |||
212 | ||||
213 | bool TargetRecip::operator==(const TargetRecip &Other) const { | |||
214 | for (const auto &KV : RecipMap) { | |||
215 | StringRef Op = KV.first; | |||
216 | const RecipParams &RP = KV.second; | |||
217 | const RecipParams &OtherRP = Other.RecipMap.find(Op)->second; | |||
218 | if (RP.RefinementSteps != OtherRP.RefinementSteps) | |||
219 | return false; | |||
220 | if (RP.Enabled != OtherRP.Enabled) | |||
221 | return false; | |||
222 | } | |||
223 | return true; | |||
224 | } |