1 //===- IntrinsicEmitter.cpp - Generate intrinsic information --------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This tablegen backend emits information about intrinsic functions.
12 //===----------------------------------------------------------------------===//
14 #include "CodeGenTarget.h"
15 #include "IntrinsicEmitter.h"
17 #include "llvm/ADT/StringExtras.h"
21 //===----------------------------------------------------------------------===//
22 // IntrinsicEmitter Implementation
23 //===----------------------------------------------------------------------===//
25 void IntrinsicEmitter::run(raw_ostream
&OS
) {
26 EmitSourceFileHeader("Intrinsic Function Source Fragment", OS
);
28 std::vector
<CodeGenIntrinsic
> Ints
= LoadIntrinsics(Records
, TargetOnly
);
30 if (TargetOnly
&& !Ints
.empty())
31 TargetPrefix
= Ints
[0].TargetPrefix
;
33 // Emit the enum information.
34 EmitEnumInfo(Ints
, OS
);
36 // Emit the intrinsic ID -> name table.
37 EmitIntrinsicToNameTable(Ints
, OS
);
39 // Emit the intrinsic ID -> overload table.
40 EmitIntrinsicToOverloadTable(Ints
, OS
);
42 // Emit the function name recognizer.
43 EmitFnNameRecognizer(Ints
, OS
);
45 // Emit the intrinsic verifier.
46 EmitVerifier(Ints
, OS
);
48 // Emit the intrinsic declaration generator.
49 EmitGenerator(Ints
, OS
);
51 // Emit the intrinsic parameter attributes.
52 EmitAttributes(Ints
, OS
);
54 // Emit intrinsic alias analysis mod/ref behavior.
55 EmitModRefBehavior(Ints
, OS
);
57 // Emit a list of intrinsics with corresponding GCC builtins.
58 EmitGCCBuiltinList(Ints
, OS
);
60 // Emit code to translate GCC builtins into LLVM intrinsics.
61 EmitIntrinsicToGCCBuiltinMap(Ints
, OS
);
64 void IntrinsicEmitter::EmitEnumInfo(const std::vector
<CodeGenIntrinsic
> &Ints
,
66 OS
<< "// Enum values for Intrinsics.h\n";
67 OS
<< "#ifdef GET_INTRINSIC_ENUM_VALUES\n";
68 for (unsigned i
= 0, e
= Ints
.size(); i
!= e
; ++i
) {
69 OS
<< " " << Ints
[i
].EnumName
;
70 OS
<< ((i
!= e
-1) ? ", " : " ");
71 OS
<< std::string(40-Ints
[i
].EnumName
.size(), ' ')
72 << "// " << Ints
[i
].Name
<< "\n";
77 void IntrinsicEmitter::
78 EmitFnNameRecognizer(const std::vector
<CodeGenIntrinsic
> &Ints
,
80 // Build a function name -> intrinsic name mapping.
81 std::map
<std::string
, unsigned> IntMapping
;
82 for (unsigned i
= 0, e
= Ints
.size(); i
!= e
; ++i
)
83 IntMapping
[Ints
[i
].Name
] = i
;
85 OS
<< "// Function name -> enum value recognizer code.\n";
86 OS
<< "#ifdef GET_FUNCTION_RECOGNIZER\n";
87 OS
<< " switch (Name[5]) {\n";
89 // Emit the intrinsics in sorted order.
91 for (std::map
<std::string
, unsigned>::iterator I
= IntMapping
.begin(),
92 E
= IntMapping
.end(); I
!= E
; ++I
) {
93 if (I
->first
[5] != LastChar
) {
94 LastChar
= I
->first
[5];
96 OS
<< " case '" << LastChar
<< "':\n";
99 // For overloaded intrinsics, only the prefix needs to match
100 if (Ints
[I
->second
].isOverloaded
)
101 OS
<< " if (Len > " << I
->first
.size()
102 << " && !memcmp(Name, \"" << I
->first
<< ".\", "
103 << (I
->first
.size() + 1) << ")) return " << TargetPrefix
<< "Intrinsic::"
104 << Ints
[I
->second
].EnumName
<< ";\n";
106 OS
<< " if (Len == " << I
->first
.size()
107 << " && !memcmp(Name, \"" << I
->first
<< "\", "
108 << I
->first
.size() << ")) return " << TargetPrefix
<< "Intrinsic::"
109 << Ints
[I
->second
].EnumName
<< ";\n";
115 void IntrinsicEmitter::
116 EmitIntrinsicToNameTable(const std::vector
<CodeGenIntrinsic
> &Ints
,
118 OS
<< "// Intrinsic ID to name table\n";
119 OS
<< "#ifdef GET_INTRINSIC_NAME_TABLE\n";
120 OS
<< " // Note that entry #0 is the invalid intrinsic!\n";
121 for (unsigned i
= 0, e
= Ints
.size(); i
!= e
; ++i
)
122 OS
<< " \"" << Ints
[i
].Name
<< "\",\n";
126 void IntrinsicEmitter::
127 EmitIntrinsicToOverloadTable(const std::vector
<CodeGenIntrinsic
> &Ints
,
129 OS
<< "// Intrinsic ID to overload table\n";
130 OS
<< "#ifdef GET_INTRINSIC_OVERLOAD_TABLE\n";
131 OS
<< " // Note that entry #0 is the invalid intrinsic!\n";
132 for (unsigned i
= 0, e
= Ints
.size(); i
!= e
; ++i
) {
134 if (Ints
[i
].isOverloaded
)
143 static void EmitTypeForValueType(raw_ostream
&OS
, MVT::SimpleValueType VT
) {
144 if (EVT(VT
).isInteger()) {
145 unsigned BitWidth
= EVT(VT
).getSizeInBits();
146 OS
<< "IntegerType::get(Context, " << BitWidth
<< ")";
147 } else if (VT
== MVT::Other
) {
148 // MVT::OtherVT is used to mean the empty struct type here.
149 OS
<< "StructType::get(Context)";
150 } else if (VT
== MVT::f32
) {
151 OS
<< "Type::getFloatTy(Context)";
152 } else if (VT
== MVT::f64
) {
153 OS
<< "Type::getDoubleTy(Context)";
154 } else if (VT
== MVT::f80
) {
155 OS
<< "Type::getX86_FP80Ty(Context)";
156 } else if (VT
== MVT::f128
) {
157 OS
<< "Type::getFP128Ty(Context)";
158 } else if (VT
== MVT::ppcf128
) {
159 OS
<< "Type::getPPC_FP128Ty(Context)";
160 } else if (VT
== MVT::isVoid
) {
161 OS
<< "Type::getVoidTy(Context)";
162 } else if (VT
== MVT::Metadata
) {
163 OS
<< "Type::getMetadataTy(Context)";
165 assert(false && "Unsupported ValueType!");
169 static void EmitTypeGenerate(raw_ostream
&OS
, const Record
*ArgType
,
172 static void EmitTypeGenerate(raw_ostream
&OS
,
173 const std::vector
<Record
*> &ArgTypes
,
175 if (ArgTypes
.size() == 1) {
176 EmitTypeGenerate(OS
, ArgTypes
.front(), ArgNo
);
180 OS
<< "StructType::get(Context, ";
182 for (std::vector
<Record
*>::const_iterator
183 I
= ArgTypes
.begin(), E
= ArgTypes
.end(); I
!= E
; ++I
) {
184 EmitTypeGenerate(OS
, *I
, ArgNo
);
191 static void EmitTypeGenerate(raw_ostream
&OS
, const Record
*ArgType
,
193 MVT::SimpleValueType VT
= getValueType(ArgType
->getValueAsDef("VT"));
195 if (ArgType
->isSubClassOf("LLVMMatchType")) {
196 unsigned Number
= ArgType
->getValueAsInt("Number");
197 assert(Number
< ArgNo
&& "Invalid matching number!");
198 if (ArgType
->isSubClassOf("LLVMExtendedElementVectorType"))
199 OS
<< "VectorType::getExtendedElementVectorType"
200 << "(dyn_cast<VectorType>(Tys[" << Number
<< "]))";
201 else if (ArgType
->isSubClassOf("LLVMTruncatedElementVectorType"))
202 OS
<< "VectorType::getTruncatedElementVectorType"
203 << "(dyn_cast<VectorType>(Tys[" << Number
<< "]))";
205 OS
<< "Tys[" << Number
<< "]";
206 } else if (VT
== MVT::iAny
|| VT
== MVT::fAny
|| VT
== MVT::vAny
) {
207 // NOTE: The ArgNo variable here is not the absolute argument number, it is
208 // the index of the "arbitrary" type in the Tys array passed to the
209 // Intrinsic::getDeclaration function. Consequently, we only want to
210 // increment it when we actually hit an overloaded type. Getting this wrong
211 // leads to very subtle bugs!
212 OS
<< "Tys[" << ArgNo
++ << "]";
213 } else if (EVT(VT
).isVector()) {
215 OS
<< "VectorType::get(";
216 EmitTypeForValueType(OS
, VVT
.getVectorElementType().getSimpleVT().SimpleTy
);
217 OS
<< ", " << VVT
.getVectorNumElements() << ")";
218 } else if (VT
== MVT::iPTR
) {
219 OS
<< "PointerType::getUnqual(";
220 EmitTypeGenerate(OS
, ArgType
->getValueAsDef("ElTy"), ArgNo
);
222 } else if (VT
== MVT::iPTRAny
) {
223 // Make sure the user has passed us an argument type to overload. If not,
224 // treat it as an ordinary (not overloaded) intrinsic.
225 OS
<< "(" << ArgNo
<< " < numTys) ? Tys[" << ArgNo
226 << "] : PointerType::getUnqual(";
227 EmitTypeGenerate(OS
, ArgType
->getValueAsDef("ElTy"), ArgNo
);
230 } else if (VT
== MVT::isVoid
) {
232 OS
<< "Type::getVoidTy(Context)";
234 // MVT::isVoid is used to mean varargs here.
237 EmitTypeForValueType(OS
, VT
);
241 /// RecordListComparator - Provide a deterministic comparator for lists of
244 typedef std::pair
<std::vector
<Record
*>, std::vector
<Record
*> > RecPair
;
245 struct RecordListComparator
{
246 bool operator()(const RecPair
&LHS
,
247 const RecPair
&RHS
) const {
249 const std::vector
<Record
*> *LHSVec
= &LHS
.first
;
250 const std::vector
<Record
*> *RHSVec
= &RHS
.first
;
251 unsigned RHSSize
= RHSVec
->size();
252 unsigned LHSSize
= LHSVec
->size();
255 if (i
== RHSSize
) return false; // RHS is shorter than LHS.
256 if ((*LHSVec
)[i
] != (*RHSVec
)[i
])
257 return (*LHSVec
)[i
]->getName() < (*RHSVec
)[i
]->getName();
258 } while (++i
!= LHSSize
);
260 if (i
!= RHSSize
) return true;
263 LHSVec
= &LHS
.second
;
264 RHSVec
= &RHS
.second
;
265 RHSSize
= RHSVec
->size();
266 LHSSize
= LHSVec
->size();
268 for (i
= 0; i
!= LHSSize
; ++i
) {
269 if (i
== RHSSize
) return false; // RHS is shorter than LHS.
270 if ((*LHSVec
)[i
] != (*RHSVec
)[i
])
271 return (*LHSVec
)[i
]->getName() < (*RHSVec
)[i
]->getName();
279 void IntrinsicEmitter::EmitVerifier(const std::vector
<CodeGenIntrinsic
> &Ints
,
281 OS
<< "// Verifier::visitIntrinsicFunctionCall code.\n";
282 OS
<< "#ifdef GET_INTRINSIC_VERIFIER\n";
283 OS
<< " switch (ID) {\n";
284 OS
<< " default: assert(0 && \"Invalid intrinsic!\");\n";
286 // This checking can emit a lot of very common code. To reduce the amount of
287 // code that we emit, batch up cases that have identical types. This avoids
288 // problems where GCC can run out of memory compiling Verifier.cpp.
289 typedef std::map
<RecPair
, std::vector
<unsigned>, RecordListComparator
> MapTy
;
290 MapTy UniqueArgInfos
;
292 // Compute the unique argument type info.
293 for (unsigned i
= 0, e
= Ints
.size(); i
!= e
; ++i
)
294 UniqueArgInfos
[make_pair(Ints
[i
].IS
.RetTypeDefs
,
295 Ints
[i
].IS
.ParamTypeDefs
)].push_back(i
);
297 // Loop through the array, emitting one comparison for each batch.
298 for (MapTy::iterator I
= UniqueArgInfos
.begin(),
299 E
= UniqueArgInfos
.end(); I
!= E
; ++I
) {
300 for (unsigned i
= 0, e
= I
->second
.size(); i
!= e
; ++i
)
301 OS
<< " case Intrinsic::" << Ints
[I
->second
[i
]].EnumName
<< ":\t\t// "
302 << Ints
[I
->second
[i
]].Name
<< "\n";
304 const RecPair
&ArgTypes
= I
->first
;
305 const std::vector
<Record
*> &RetTys
= ArgTypes
.first
;
306 const std::vector
<Record
*> &ParamTys
= ArgTypes
.second
;
307 std::vector
<unsigned> OverloadedTypeIndices
;
309 OS
<< " VerifyIntrinsicPrototype(ID, IF, " << RetTys
.size() << ", "
312 // Emit return types.
313 for (unsigned j
= 0, je
= RetTys
.size(); j
!= je
; ++j
) {
314 Record
*ArgType
= RetTys
[j
];
317 if (ArgType
->isSubClassOf("LLVMMatchType")) {
318 unsigned Number
= ArgType
->getValueAsInt("Number");
319 assert(Number
< OverloadedTypeIndices
.size() &&
320 "Invalid matching number!");
321 Number
= OverloadedTypeIndices
[Number
];
322 if (ArgType
->isSubClassOf("LLVMExtendedElementVectorType"))
323 OS
<< "~(ExtendedElementVectorType | " << Number
<< ")";
324 else if (ArgType
->isSubClassOf("LLVMTruncatedElementVectorType"))
325 OS
<< "~(TruncatedElementVectorType | " << Number
<< ")";
329 MVT::SimpleValueType VT
= getValueType(ArgType
->getValueAsDef("VT"));
330 OS
<< getEnumName(VT
);
332 if (EVT(VT
).isOverloaded())
333 OverloadedTypeIndices
.push_back(j
);
335 if (VT
== MVT::isVoid
&& j
!= 0 && j
!= je
- 1)
336 throw "Var arg type not last argument";
340 // Emit the parameter types.
341 for (unsigned j
= 0, je
= ParamTys
.size(); j
!= je
; ++j
) {
342 Record
*ArgType
= ParamTys
[j
];
345 if (ArgType
->isSubClassOf("LLVMMatchType")) {
346 unsigned Number
= ArgType
->getValueAsInt("Number");
347 assert(Number
< OverloadedTypeIndices
.size() &&
348 "Invalid matching number!");
349 Number
= OverloadedTypeIndices
[Number
];
350 if (ArgType
->isSubClassOf("LLVMExtendedElementVectorType"))
351 OS
<< "~(ExtendedElementVectorType | " << Number
<< ")";
352 else if (ArgType
->isSubClassOf("LLVMTruncatedElementVectorType"))
353 OS
<< "~(TruncatedElementVectorType | " << Number
<< ")";
357 MVT::SimpleValueType VT
= getValueType(ArgType
->getValueAsDef("VT"));
358 OS
<< getEnumName(VT
);
360 if (EVT(VT
).isOverloaded())
361 OverloadedTypeIndices
.push_back(j
+ RetTys
.size());
363 if (VT
== MVT::isVoid
&& j
!= 0 && j
!= je
- 1)
364 throw "Var arg type not last argument";
375 void IntrinsicEmitter::EmitGenerator(const std::vector
<CodeGenIntrinsic
> &Ints
,
377 OS
<< "// Code for generating Intrinsic function declarations.\n";
378 OS
<< "#ifdef GET_INTRINSIC_GENERATOR\n";
379 OS
<< " switch (id) {\n";
380 OS
<< " default: assert(0 && \"Invalid intrinsic!\");\n";
382 // Similar to GET_INTRINSIC_VERIFIER, batch up cases that have identical
384 typedef std::map
<RecPair
, std::vector
<unsigned>, RecordListComparator
> MapTy
;
385 MapTy UniqueArgInfos
;
387 // Compute the unique argument type info.
388 for (unsigned i
= 0, e
= Ints
.size(); i
!= e
; ++i
)
389 UniqueArgInfos
[make_pair(Ints
[i
].IS
.RetTypeDefs
,
390 Ints
[i
].IS
.ParamTypeDefs
)].push_back(i
);
392 // Loop through the array, emitting one generator for each batch.
393 std::string IntrinsicStr
= TargetPrefix
+ "Intrinsic::";
395 for (MapTy::iterator I
= UniqueArgInfos
.begin(),
396 E
= UniqueArgInfos
.end(); I
!= E
; ++I
) {
397 for (unsigned i
= 0, e
= I
->second
.size(); i
!= e
; ++i
)
398 OS
<< " case " << IntrinsicStr
<< Ints
[I
->second
[i
]].EnumName
399 << ":\t\t// " << Ints
[I
->second
[i
]].Name
<< "\n";
401 const RecPair
&ArgTypes
= I
->first
;
402 const std::vector
<Record
*> &RetTys
= ArgTypes
.first
;
403 const std::vector
<Record
*> &ParamTys
= ArgTypes
.second
;
405 unsigned N
= ParamTys
.size();
408 getValueType(ParamTys
[N
- 1]->getValueAsDef("VT")) == MVT::isVoid
) {
409 OS
<< " IsVarArg = true;\n";
414 OS
<< " ResultTy = ";
415 EmitTypeGenerate(OS
, RetTys
, ArgNo
);
418 for (unsigned j
= 0; j
!= N
; ++j
) {
419 OS
<< " ArgTys.push_back(";
420 EmitTypeGenerate(OS
, ParamTys
[j
], ArgNo
);
431 /// EmitAttributes - This emits the Intrinsic::getAttributes method.
432 void IntrinsicEmitter::
433 EmitAttributes(const std::vector
<CodeGenIntrinsic
> &Ints
, raw_ostream
&OS
) {
434 OS
<< "// Add parameter attributes that are not common to all intrinsics.\n";
435 OS
<< "#ifdef GET_INTRINSIC_ATTRIBUTES\n";
437 OS
<< "static AttrListPtr getAttributes(" << TargetPrefix
438 << "Intrinsic::ID id) {";
440 OS
<< "AttrListPtr Intrinsic::getAttributes(ID id) {";
441 OS
<< " // No intrinsic can throw exceptions.\n";
442 OS
<< " Attributes Attr = Attribute::NoUnwind;\n";
443 OS
<< " switch (id) {\n";
444 OS
<< " default: break;\n";
445 unsigned MaxArgAttrs
= 0;
446 for (unsigned i
= 0, e
= Ints
.size(); i
!= e
; ++i
) {
448 std::max(MaxArgAttrs
, unsigned(Ints
[i
].ArgumentAttributes
.size()));
449 switch (Ints
[i
].ModRef
) {
451 case CodeGenIntrinsic::NoMem
:
452 OS
<< " case " << TargetPrefix
<< "Intrinsic::" << Ints
[i
].EnumName
457 OS
<< " Attr |= Attribute::ReadNone; // These do not access memory.\n";
459 for (unsigned i
= 0, e
= Ints
.size(); i
!= e
; ++i
) {
460 switch (Ints
[i
].ModRef
) {
462 case CodeGenIntrinsic::ReadArgMem
:
463 case CodeGenIntrinsic::ReadMem
:
464 OS
<< " case " << TargetPrefix
<< "Intrinsic::" << Ints
[i
].EnumName
469 OS
<< " Attr |= Attribute::ReadOnly; // These do not write memory.\n";
472 OS
<< " AttributeWithIndex AWI[" << MaxArgAttrs
+1 << "];\n";
473 OS
<< " unsigned NumAttrs = 0;\n";
474 OS
<< " switch (id) {\n";
475 OS
<< " default: break;\n";
477 // Add argument attributes for any intrinsics that have them.
478 for (unsigned i
= 0, e
= Ints
.size(); i
!= e
; ++i
) {
479 if (Ints
[i
].ArgumentAttributes
.empty()) continue;
481 OS
<< " case " << TargetPrefix
<< "Intrinsic::" << Ints
[i
].EnumName
484 std::vector
<std::pair
<unsigned, CodeGenIntrinsic::ArgAttribute
> > ArgAttrs
=
485 Ints
[i
].ArgumentAttributes
;
486 // Sort by argument index.
487 std::sort(ArgAttrs
.begin(), ArgAttrs
.end());
489 unsigned NumArgsWithAttrs
= 0;
491 while (!ArgAttrs
.empty()) {
492 unsigned ArgNo
= ArgAttrs
[0].first
;
494 OS
<< " AWI[" << NumArgsWithAttrs
++ << "] = AttributeWithIndex::get("
497 while (!ArgAttrs
.empty() && ArgAttrs
[0].first
== ArgNo
) {
498 switch (ArgAttrs
[0].second
) {
499 default: assert(0 && "Unknown arg attribute");
500 case CodeGenIntrinsic::NoCapture
:
501 OS
<< "|Attribute::NoCapture";
504 ArgAttrs
.erase(ArgAttrs
.begin());
509 OS
<< " NumAttrs = " << NumArgsWithAttrs
<< ";\n";
514 OS
<< " AWI[NumAttrs] = AttributeWithIndex::get(~0, Attr);\n";
515 OS
<< " return AttrListPtr::get(AWI, NumAttrs+1);\n";
517 OS
<< "#endif // GET_INTRINSIC_ATTRIBUTES\n\n";
520 /// EmitModRefBehavior - Determine intrinsic alias analysis mod/ref behavior.
521 void IntrinsicEmitter::
522 EmitModRefBehavior(const std::vector
<CodeGenIntrinsic
> &Ints
, raw_ostream
&OS
){
523 OS
<< "// Determine intrinsic alias analysis mod/ref behavior.\n";
524 OS
<< "#ifdef GET_INTRINSIC_MODREF_BEHAVIOR\n";
525 OS
<< "switch (id) {\n";
526 OS
<< "default:\n return UnknownModRefBehavior;\n";
527 for (unsigned i
= 0, e
= Ints
.size(); i
!= e
; ++i
) {
528 if (Ints
[i
].ModRef
== CodeGenIntrinsic::WriteMem
)
530 OS
<< "case " << TargetPrefix
<< "Intrinsic::" << Ints
[i
].EnumName
532 switch (Ints
[i
].ModRef
) {
534 assert(false && "Unknown Mod/Ref type!");
535 case CodeGenIntrinsic::NoMem
:
536 OS
<< " return DoesNotAccessMemory;\n";
538 case CodeGenIntrinsic::ReadArgMem
:
539 case CodeGenIntrinsic::ReadMem
:
540 OS
<< " return OnlyReadsMemory;\n";
542 case CodeGenIntrinsic::WriteArgMem
:
543 OS
<< " return AccessesArguments;\n";
548 OS
<< "#endif // GET_INTRINSIC_MODREF_BEHAVIOR\n\n";
551 void IntrinsicEmitter::
552 EmitGCCBuiltinList(const std::vector
<CodeGenIntrinsic
> &Ints
, raw_ostream
&OS
){
553 OS
<< "// Get the GCC builtin that corresponds to an LLVM intrinsic.\n";
554 OS
<< "#ifdef GET_GCC_BUILTIN_NAME\n";
555 OS
<< " switch (F->getIntrinsicID()) {\n";
556 OS
<< " default: BuiltinName = \"\"; break;\n";
557 for (unsigned i
= 0, e
= Ints
.size(); i
!= e
; ++i
) {
558 if (!Ints
[i
].GCCBuiltinName
.empty()) {
559 OS
<< " case Intrinsic::" << Ints
[i
].EnumName
<< ": BuiltinName = \""
560 << Ints
[i
].GCCBuiltinName
<< "\"; break;\n";
567 /// EmitBuiltinComparisons - Emit comparisons to determine whether the specified
568 /// sorted range of builtin names is equal to the current builtin. This breaks
569 /// it down into a simple tree.
571 /// At this point, we know that all the builtins in the range have the same name
572 /// for the first 'CharStart' characters. Only the end of the name needs to be
574 typedef std::map
<std::string
, std::string
>::const_iterator StrMapIterator
;
575 static void EmitBuiltinComparisons(StrMapIterator Start
, StrMapIterator End
,
576 unsigned CharStart
, unsigned Indent
,
577 std::string TargetPrefix
, raw_ostream
&OS
) {
578 if (Start
== End
) return; // empty range.
580 // Determine what, if anything, is the same about all these strings.
581 std::string CommonString
= Start
->first
;
582 unsigned NumInRange
= 0;
583 for (StrMapIterator I
= Start
; I
!= End
; ++I
, ++NumInRange
) {
584 // Find the first character that doesn't match.
585 const std::string
&ThisStr
= I
->first
;
586 unsigned NonMatchChar
= CharStart
;
587 while (NonMatchChar
< CommonString
.size() &&
588 NonMatchChar
< ThisStr
.size() &&
589 CommonString
[NonMatchChar
] == ThisStr
[NonMatchChar
])
591 // Truncate off pieces that don't match.
592 CommonString
.resize(NonMatchChar
);
595 // Just compare the rest of the string.
596 if (NumInRange
== 1) {
597 if (CharStart
!= CommonString
.size()) {
598 OS
<< std::string(Indent
*2, ' ') << "if (!memcmp(BuiltinName";
599 if (CharStart
) OS
<< "+" << CharStart
;
600 OS
<< ", \"" << (CommonString
.c_str()+CharStart
) << "\", ";
601 OS
<< CommonString
.size() - CharStart
<< "))\n";
604 OS
<< std::string(Indent
*2, ' ') << "IntrinsicID = " << TargetPrefix
606 OS
<< Start
->second
<< ";\n";
610 // At this point, we potentially have a common prefix for these builtins, emit
611 // a check for this common prefix.
612 if (CommonString
.size() != CharStart
) {
613 OS
<< std::string(Indent
*2, ' ') << "if (!memcmp(BuiltinName";
614 if (CharStart
) OS
<< "+" << CharStart
;
615 OS
<< ", \"" << (CommonString
.c_str()+CharStart
) << "\", ";
616 OS
<< CommonString
.size()-CharStart
<< ")) {\n";
618 EmitBuiltinComparisons(Start
, End
, CommonString
.size(), Indent
+1,
620 OS
<< std::string(Indent
*2, ' ') << "}\n";
624 // Output a switch on the character that differs across the set.
625 OS
<< std::string(Indent
*2, ' ') << "switch (BuiltinName[" << CharStart
628 OS
<< " // \"" << std::string(Start
->first
.begin(),
629 Start
->first
.begin()+CharStart
) << "\"";
632 for (StrMapIterator I
= Start
; I
!= End
; ) {
633 char ThisChar
= I
->first
[CharStart
];
634 OS
<< std::string(Indent
*2, ' ') << "case '" << ThisChar
<< "':\n";
635 // Figure out the range that has this common character.
636 StrMapIterator NextChar
= I
;
637 for (++NextChar
; NextChar
!= End
&& NextChar
->first
[CharStart
] == ThisChar
;
640 EmitBuiltinComparisons(I
, NextChar
, CharStart
+1, Indent
+1, TargetPrefix
,OS
);
641 OS
<< std::string(Indent
*2, ' ') << " break;\n";
644 OS
<< std::string(Indent
*2, ' ') << "}\n";
647 /// EmitTargetBuiltins - All of the builtins in the specified map are for the
648 /// same target, and we already checked it.
649 static void EmitTargetBuiltins(const std::map
<std::string
, std::string
> &BIM
,
650 const std::string
&TargetPrefix
,
652 // Rearrange the builtins by length.
653 std::vector
<std::map
<std::string
, std::string
> > BuiltinsByLen
;
654 BuiltinsByLen
.reserve(100);
656 for (StrMapIterator I
= BIM
.begin(), E
= BIM
.end(); I
!= E
; ++I
) {
657 if (I
->first
.size() >= BuiltinsByLen
.size())
658 BuiltinsByLen
.resize(I
->first
.size()+1);
659 BuiltinsByLen
[I
->first
.size()].insert(*I
);
662 // Now that we have all the builtins by their length, emit a switch stmt.
663 OS
<< " switch (strlen(BuiltinName)) {\n";
664 OS
<< " default: break;\n";
665 for (unsigned i
= 0, e
= BuiltinsByLen
.size(); i
!= e
; ++i
) {
666 if (BuiltinsByLen
[i
].empty()) continue;
667 OS
<< " case " << i
<< ":\n";
668 EmitBuiltinComparisons(BuiltinsByLen
[i
].begin(), BuiltinsByLen
[i
].end(),
669 0, 3, TargetPrefix
, OS
);
676 void IntrinsicEmitter::
677 EmitIntrinsicToGCCBuiltinMap(const std::vector
<CodeGenIntrinsic
> &Ints
,
679 typedef std::map
<std::string
, std::map
<std::string
, std::string
> > BIMTy
;
681 for (unsigned i
= 0, e
= Ints
.size(); i
!= e
; ++i
) {
682 if (!Ints
[i
].GCCBuiltinName
.empty()) {
683 // Get the map for this target prefix.
684 std::map
<std::string
, std::string
> &BIM
=BuiltinMap
[Ints
[i
].TargetPrefix
];
686 if (!BIM
.insert(std::make_pair(Ints
[i
].GCCBuiltinName
,
687 Ints
[i
].EnumName
)).second
)
688 throw "Intrinsic '" + Ints
[i
].TheDef
->getName() +
689 "': duplicate GCC builtin name!";
693 OS
<< "// Get the LLVM intrinsic that corresponds to a GCC builtin.\n";
694 OS
<< "// This is used by the C front-end. The GCC builtin name is passed\n";
695 OS
<< "// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed\n";
696 OS
<< "// in as TargetPrefix. The result is assigned to 'IntrinsicID'.\n";
697 OS
<< "#ifdef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN\n";
700 OS
<< "static " << TargetPrefix
<< "Intrinsic::ID "
701 << "getIntrinsicForGCCBuiltin(const char "
702 << "*TargetPrefix, const char *BuiltinName) {\n";
703 OS
<< " " << TargetPrefix
<< "Intrinsic::ID IntrinsicID = ";
705 OS
<< "Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char "
706 << "*TargetPrefix, const char *BuiltinName) {\n";
707 OS
<< " Intrinsic::ID IntrinsicID = ";
711 OS
<< "(" << TargetPrefix
<< "Intrinsic::ID)";
713 OS
<< "Intrinsic::not_intrinsic;\n";
715 // Note: this could emit significantly better code if we cared.
716 for (BIMTy::iterator I
= BuiltinMap
.begin(), E
= BuiltinMap
.end();I
!= E
;++I
){
718 if (!I
->first
.empty())
719 OS
<< "if (!strcmp(TargetPrefix, \"" << I
->first
<< "\")) ";
721 OS
<< "/* Target Independent Builtins */ ";
724 // Emit the comparisons for this target prefix.
725 EmitTargetBuiltins(I
->second
, TargetPrefix
, OS
);
728 OS
<< " return IntrinsicID;\n";