File: | lib/Target/TargetRecip.cpp |
Warning: | line 152, column 32 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/StringExtras.h" | |||
20 | #include "llvm/ADT/StringRef.h" | |||
21 | #include "llvm/ADT/SmallVector.h" | |||
22 | #include "llvm/Support/ErrorHandling.h" | |||
23 | ||||
24 | using namespace llvm; | |||
25 | ||||
26 | // These are the names of the individual reciprocal operations. These are | |||
27 | // the key strings for queries and command-line inputs. | |||
28 | // In addition, the command-line interface recognizes the global parameters | |||
29 | // "all", "none", and "default". | |||
30 | static const char *const RecipOps[] = { | |||
31 | "divd", | |||
32 | "divf", | |||
33 | "vec-divd", | |||
34 | "vec-divf", | |||
35 | "sqrtd", | |||
36 | "sqrtf", | |||
37 | "vec-sqrtd", | |||
38 | "vec-sqrtf", | |||
39 | }; | |||
40 | ||||
41 | /// All operations are disabled by default and refinement steps are set to zero. | |||
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-4.0~svn284574/lib/Target/TargetRecip.cpp" , 137, __PRETTY_FUNCTION__)); | |||
138 | report_fatal_error("Invalid option for -recip."); | |||
139 | } | |||
140 | } | |||
141 | ||||
142 | // Mark the matched option as found. Do not allow duplicate specifiers. | |||
143 | Iter->second.Enabled = !IsDisabled; | |||
144 | if (!RefStepString.empty()) | |||
145 | Iter->second.RefinementSteps = RefSteps; | |||
146 | ||||
147 | // If the precision was not specified, the double entry is also initialized. | |||
148 | if (Val.back() != 'f' && Val.back() != 'd') { | |||
149 | RecipParams &Params = RecipMap[Val.str() + 'd']; | |||
150 | Params.Enabled = !IsDisabled; | |||
151 | if (!RefStepString.empty()) | |||
152 | Params.RefinementSteps = RefSteps; | |||
| ||||
153 | } | |||
154 | } | |||
155 | } | |||
156 | ||||
157 | void TargetRecip::set(StringRef &RecipString) { | |||
158 | SmallVector<StringRef, 4> RecipStringVector; | |||
159 | SplitString(RecipString, RecipStringVector, ","); | |||
160 | std::vector<std::string> RecipVector; | |||
161 | for (unsigned i = 0; i < RecipStringVector.size(); ++i) | |||
| ||||
162 | RecipVector.push_back(RecipStringVector[i].str()); | |||
163 | ||||
164 | unsigned NumArgs = RecipVector.size(); | |||
165 | ||||
166 | // Check if "all", "default", or "none" was specified. | |||
167 | if (NumArgs == 1 && parseGlobalParams(RecipVector[0])) | |||
168 | return; | |||
169 | ||||
170 | parseIndividualParams(RecipVector); | |||
171 | } | |||
172 | ||||
173 | bool TargetRecip::isEnabled(StringRef Key) const { | |||
174 | ConstRecipIter Iter = RecipMap.find(Key); | |||
175 | 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-4.0~svn284574/lib/Target/TargetRecip.cpp" , 175, __PRETTY_FUNCTION__)); | |||
176 | return Iter->second.Enabled; | |||
177 | } | |||
178 | ||||
179 | unsigned TargetRecip::getRefinementSteps(StringRef Key) const { | |||
180 | ConstRecipIter Iter = RecipMap.find(Key); | |||
181 | 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-4.0~svn284574/lib/Target/TargetRecip.cpp" , 181, __PRETTY_FUNCTION__)); | |||
182 | return Iter->second.RefinementSteps; | |||
183 | } | |||
184 | ||||
185 | void TargetRecip::set(StringRef Key, bool Enable, unsigned RefSteps) { | |||
186 | if (Key == "all") { | |||
187 | for (auto &KV : RecipMap) { | |||
188 | RecipParams &RP = KV.second; | |||
189 | RP.Enabled = Enable; | |||
190 | RP.RefinementSteps = RefSteps; | |||
191 | } | |||
192 | } else { | |||
193 | RecipParams &RP = RecipMap[Key]; | |||
194 | RP.Enabled = Enable; | |||
195 | RP.RefinementSteps = RefSteps; | |||
196 | } | |||
197 | } | |||
198 | ||||
199 | bool TargetRecip::operator==(const TargetRecip &Other) const { | |||
200 | for (const auto &KV : RecipMap) { | |||
201 | StringRef Op = KV.first; | |||
202 | const RecipParams &RP = KV.second; | |||
203 | const RecipParams &OtherRP = Other.RecipMap.find(Op)->second; | |||
204 | if (RP.RefinementSteps != OtherRP.RefinementSteps) | |||
205 | return false; | |||
206 | if (RP.Enabled != OtherRP.Enabled) | |||
207 | return false; | |||
208 | } | |||
209 | return true; | |||
210 | } |