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(std::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(std::ostream
&OS
, MVT::SimpleValueType VT
) {
144 if (MVT(VT
).isInteger()) {
145 unsigned BitWidth
= MVT(VT
).getSizeInBits();
146 OS
<< "IntegerType::get(" << BitWidth
<< ")";
147 } else if (VT
== MVT::Other
) {
148 // MVT::OtherVT is used to mean the empty struct type here.
149 OS
<< "StructType::get(std::vector<const Type *>())";
150 } else if (VT
== MVT::f32
) {
151 OS
<< "Type::FloatTy";
152 } else if (VT
== MVT::f64
) {
153 OS
<< "Type::DoubleTy";
154 } else if (VT
== MVT::f80
) {
155 OS
<< "Type::X86_FP80Ty";
156 } else if (VT
== MVT::f128
) {
157 OS
<< "Type::FP128Ty";
158 } else if (VT
== MVT::ppcf128
) {
159 OS
<< "Type::PPC_FP128Ty";
160 } else if (VT
== MVT::isVoid
) {
161 OS
<< "Type::VoidTy";
163 assert(false && "Unsupported ValueType!");
167 static void EmitTypeGenerate(std::ostream
&OS
, const Record
*ArgType
,
170 static void EmitTypeGenerate(std::ostream
&OS
,
171 const std::vector
<Record
*> &ArgTypes
,
173 if (ArgTypes
.size() == 1) {
174 EmitTypeGenerate(OS
, ArgTypes
.front(), ArgNo
);
178 OS
<< "StructType::get(";
180 for (std::vector
<Record
*>::const_iterator
181 I
= ArgTypes
.begin(), E
= ArgTypes
.end(); I
!= E
; ++I
) {
182 EmitTypeGenerate(OS
, *I
, ArgNo
);
189 static void EmitTypeGenerate(std::ostream
&OS
, const Record
*ArgType
,
191 MVT::SimpleValueType VT
= getValueType(ArgType
->getValueAsDef("VT"));
193 if (ArgType
->isSubClassOf("LLVMMatchType")) {
194 unsigned Number
= ArgType
->getValueAsInt("Number");
195 assert(Number
< ArgNo
&& "Invalid matching number!");
196 if (ArgType
->isSubClassOf("LLVMExtendedElementVectorType"))
197 OS
<< "VectorType::getExtendedElementVectorType"
198 << "(dyn_cast<VectorType>(Tys[" << Number
<< "]))";
199 else if (ArgType
->isSubClassOf("LLVMTruncatedElementVectorType"))
200 OS
<< "VectorType::getTruncatedElementVectorType"
201 << "(dyn_cast<VectorType>(Tys[" << Number
<< "]))";
203 OS
<< "Tys[" << Number
<< "]";
204 } else if (VT
== MVT::iAny
|| VT
== MVT::fAny
) {
205 // NOTE: The ArgNo variable here is not the absolute argument number, it is
206 // the index of the "arbitrary" type in the Tys array passed to the
207 // Intrinsic::getDeclaration function. Consequently, we only want to
208 // increment it when we actually hit an overloaded type. Getting this wrong
209 // leads to very subtle bugs!
210 OS
<< "Tys[" << ArgNo
++ << "]";
211 } else if (MVT(VT
).isVector()) {
213 OS
<< "VectorType::get(";
214 EmitTypeForValueType(OS
, VVT
.getVectorElementType().getSimpleVT());
215 OS
<< ", " << VVT
.getVectorNumElements() << ")";
216 } else if (VT
== MVT::iPTR
) {
217 OS
<< "PointerType::getUnqual(";
218 EmitTypeGenerate(OS
, ArgType
->getValueAsDef("ElTy"), ArgNo
);
220 } else if (VT
== MVT::iPTRAny
) {
221 // Make sure the user has passed us an argument type to overload. If not,
222 // treat it as an ordinary (not overloaded) intrinsic.
223 OS
<< "(" << ArgNo
<< " < numTys) ? Tys[" << ArgNo
224 << "] : PointerType::getUnqual(";
225 EmitTypeGenerate(OS
, ArgType
->getValueAsDef("ElTy"), ArgNo
);
228 } else if (VT
== MVT::isVoid
) {
230 OS
<< "Type::VoidTy";
232 // MVT::isVoid is used to mean varargs here.
235 EmitTypeForValueType(OS
, VT
);
239 /// RecordListComparator - Provide a deterministic comparator for lists of
242 typedef std::pair
<std::vector
<Record
*>, std::vector
<Record
*> > RecPair
;
243 struct RecordListComparator
{
244 bool operator()(const RecPair
&LHS
,
245 const RecPair
&RHS
) const {
247 const std::vector
<Record
*> *LHSVec
= &LHS
.first
;
248 const std::vector
<Record
*> *RHSVec
= &RHS
.first
;
249 unsigned RHSSize
= RHSVec
->size();
250 unsigned LHSSize
= LHSVec
->size();
253 if (i
== RHSSize
) return false; // RHS is shorter than LHS.
254 if ((*LHSVec
)[i
] != (*RHSVec
)[i
])
255 return (*LHSVec
)[i
]->getName() < (*RHSVec
)[i
]->getName();
256 } while (++i
!= LHSSize
);
258 if (i
!= RHSSize
) return true;
261 LHSVec
= &LHS
.second
;
262 RHSVec
= &RHS
.second
;
263 RHSSize
= RHSVec
->size();
264 LHSSize
= LHSVec
->size();
266 for (i
= 0; i
!= LHSSize
; ++i
) {
267 if (i
== RHSSize
) return false; // RHS is shorter than LHS.
268 if ((*LHSVec
)[i
] != (*RHSVec
)[i
])
269 return (*LHSVec
)[i
]->getName() < (*RHSVec
)[i
]->getName();
277 void IntrinsicEmitter::EmitVerifier(const std::vector
<CodeGenIntrinsic
> &Ints
,
279 OS
<< "// Verifier::visitIntrinsicFunctionCall code.\n";
280 OS
<< "#ifdef GET_INTRINSIC_VERIFIER\n";
281 OS
<< " switch (ID) {\n";
282 OS
<< " default: assert(0 && \"Invalid intrinsic!\");\n";
284 // This checking can emit a lot of very common code. To reduce the amount of
285 // code that we emit, batch up cases that have identical types. This avoids
286 // problems where GCC can run out of memory compiling Verifier.cpp.
287 typedef std::map
<RecPair
, std::vector
<unsigned>, RecordListComparator
> MapTy
;
288 MapTy UniqueArgInfos
;
290 // Compute the unique argument type info.
291 for (unsigned i
= 0, e
= Ints
.size(); i
!= e
; ++i
)
292 UniqueArgInfos
[make_pair(Ints
[i
].IS
.RetTypeDefs
,
293 Ints
[i
].IS
.ParamTypeDefs
)].push_back(i
);
295 // Loop through the array, emitting one comparison for each batch.
296 for (MapTy::iterator I
= UniqueArgInfos
.begin(),
297 E
= UniqueArgInfos
.end(); I
!= E
; ++I
) {
298 for (unsigned i
= 0, e
= I
->second
.size(); i
!= e
; ++i
)
299 OS
<< " case Intrinsic::" << Ints
[I
->second
[i
]].EnumName
<< ":\t\t// "
300 << Ints
[I
->second
[i
]].Name
<< "\n";
302 const RecPair
&ArgTypes
= I
->first
;
303 const std::vector
<Record
*> &RetTys
= ArgTypes
.first
;
304 const std::vector
<Record
*> &ParamTys
= ArgTypes
.second
;
306 OS
<< " VerifyIntrinsicPrototype(ID, IF, " << RetTys
.size() << ", "
309 // Emit return types.
310 for (unsigned j
= 0, je
= RetTys
.size(); j
!= je
; ++j
) {
311 Record
*ArgType
= RetTys
[j
];
314 if (ArgType
->isSubClassOf("LLVMMatchType")) {
315 unsigned Number
= ArgType
->getValueAsInt("Number");
316 if (ArgType
->isSubClassOf("LLVMExtendedElementVectorType"))
317 OS
<< "~(ExtendedElementVectorType | " << Number
<< ")";
318 else if (ArgType
->isSubClassOf("LLVMTruncatedElementVectorType"))
319 OS
<< "~(TruncatedElementVectorType | " << Number
<< ")";
323 MVT::SimpleValueType VT
= getValueType(ArgType
->getValueAsDef("VT"));
324 OS
<< getEnumName(VT
);
326 if (VT
== MVT::isVoid
&& j
!= 0 && j
!= je
- 1)
327 throw "Var arg type not last argument";
331 // Emit the parameter types.
332 for (unsigned j
= 0, je
= ParamTys
.size(); j
!= je
; ++j
) {
333 Record
*ArgType
= ParamTys
[j
];
336 if (ArgType
->isSubClassOf("LLVMMatchType")) {
337 unsigned Number
= ArgType
->getValueAsInt("Number");
338 if (ArgType
->isSubClassOf("LLVMExtendedElementVectorType"))
339 OS
<< "~(ExtendedElementVectorType | " << Number
<< ")";
340 else if (ArgType
->isSubClassOf("LLVMTruncatedElementVectorType"))
341 OS
<< "~(TruncatedElementVectorType | " << Number
<< ")";
345 MVT::SimpleValueType VT
= getValueType(ArgType
->getValueAsDef("VT"));
346 OS
<< getEnumName(VT
);
348 if (VT
== MVT::isVoid
&& j
!= 0 && j
!= je
- 1)
349 throw "Var arg type not last argument";
360 void IntrinsicEmitter::EmitGenerator(const std::vector
<CodeGenIntrinsic
> &Ints
,
362 OS
<< "// Code for generating Intrinsic function declarations.\n";
363 OS
<< "#ifdef GET_INTRINSIC_GENERATOR\n";
364 OS
<< " switch (id) {\n";
365 OS
<< " default: assert(0 && \"Invalid intrinsic!\");\n";
367 // Similar to GET_INTRINSIC_VERIFIER, batch up cases that have identical
369 typedef std::map
<RecPair
, std::vector
<unsigned>, RecordListComparator
> MapTy
;
370 MapTy UniqueArgInfos
;
372 // Compute the unique argument type info.
373 for (unsigned i
= 0, e
= Ints
.size(); i
!= e
; ++i
)
374 UniqueArgInfos
[make_pair(Ints
[i
].IS
.RetTypeDefs
,
375 Ints
[i
].IS
.ParamTypeDefs
)].push_back(i
);
377 // Loop through the array, emitting one generator for each batch.
378 std::string IntrinsicStr
= TargetPrefix
+ "Intrinsic::";
380 for (MapTy::iterator I
= UniqueArgInfos
.begin(),
381 E
= UniqueArgInfos
.end(); I
!= E
; ++I
) {
382 for (unsigned i
= 0, e
= I
->second
.size(); i
!= e
; ++i
)
383 OS
<< " case " << IntrinsicStr
<< Ints
[I
->second
[i
]].EnumName
384 << ":\t\t// " << Ints
[I
->second
[i
]].Name
<< "\n";
386 const RecPair
&ArgTypes
= I
->first
;
387 const std::vector
<Record
*> &RetTys
= ArgTypes
.first
;
388 const std::vector
<Record
*> &ParamTys
= ArgTypes
.second
;
390 unsigned N
= ParamTys
.size();
393 getValueType(ParamTys
[N
- 1]->getValueAsDef("VT")) == MVT::isVoid
) {
394 OS
<< " IsVarArg = true;\n";
399 OS
<< " ResultTy = ";
400 EmitTypeGenerate(OS
, RetTys
, ArgNo
);
403 for (unsigned j
= 0; j
!= N
; ++j
) {
404 OS
<< " ArgTys.push_back(";
405 EmitTypeGenerate(OS
, ParamTys
[j
], ArgNo
);
416 /// EmitAttributes - This emits the Intrinsic::getAttributes method.
417 void IntrinsicEmitter::
418 EmitAttributes(const std::vector
<CodeGenIntrinsic
> &Ints
, std::ostream
&OS
) {
419 OS
<< "// Add parameter attributes that are not common to all intrinsics.\n";
420 OS
<< "#ifdef GET_INTRINSIC_ATTRIBUTES\n";
422 OS
<< "static AttrListPtr getAttributes(" << TargetPrefix
423 << "Intrinsic::ID id) {";
425 OS
<< "AttrListPtr Intrinsic::getAttributes(ID id) {";
426 OS
<< " // No intrinsic can throw exceptions.\n";
427 OS
<< " Attributes Attr = Attribute::NoUnwind;\n";
428 OS
<< " switch (id) {\n";
429 OS
<< " default: break;\n";
430 unsigned MaxArgAttrs
= 0;
431 for (unsigned i
= 0, e
= Ints
.size(); i
!= e
; ++i
) {
433 std::max(MaxArgAttrs
, unsigned(Ints
[i
].ArgumentAttributes
.size()));
434 switch (Ints
[i
].ModRef
) {
436 case CodeGenIntrinsic::NoMem
:
437 OS
<< " case " << TargetPrefix
<< "Intrinsic::" << Ints
[i
].EnumName
442 OS
<< " Attr |= Attribute::ReadNone; // These do not access memory.\n";
444 for (unsigned i
= 0, e
= Ints
.size(); i
!= e
; ++i
) {
445 switch (Ints
[i
].ModRef
) {
447 case CodeGenIntrinsic::ReadArgMem
:
448 case CodeGenIntrinsic::ReadMem
:
449 OS
<< " case " << TargetPrefix
<< "Intrinsic::" << Ints
[i
].EnumName
454 OS
<< " Attr |= Attribute::ReadOnly; // These do not write memory.\n";
457 OS
<< " AttributeWithIndex AWI[" << MaxArgAttrs
+1 << "];\n";
458 OS
<< " unsigned NumAttrs = 0;\n";
459 OS
<< " switch (id) {\n";
460 OS
<< " default: break;\n";
462 // Add argument attributes for any intrinsics that have them.
463 for (unsigned i
= 0, e
= Ints
.size(); i
!= e
; ++i
) {
464 if (Ints
[i
].ArgumentAttributes
.empty()) continue;
466 OS
<< " case " << TargetPrefix
<< "Intrinsic::" << Ints
[i
].EnumName
469 std::vector
<std::pair
<unsigned, CodeGenIntrinsic::ArgAttribute
> > ArgAttrs
=
470 Ints
[i
].ArgumentAttributes
;
471 // Sort by argument index.
472 std::sort(ArgAttrs
.begin(), ArgAttrs
.end());
474 unsigned NumArgsWithAttrs
= 0;
476 while (!ArgAttrs
.empty()) {
477 unsigned ArgNo
= ArgAttrs
[0].first
;
479 OS
<< " AWI[" << NumArgsWithAttrs
++ << "] = AttributeWithIndex::get("
482 while (!ArgAttrs
.empty() && ArgAttrs
[0].first
== ArgNo
) {
483 switch (ArgAttrs
[0].second
) {
484 default: assert(0 && "Unknown arg attribute");
485 case CodeGenIntrinsic::NoCapture
:
486 OS
<< "|Attribute::NoCapture";
489 ArgAttrs
.erase(ArgAttrs
.begin());
494 OS
<< " NumAttrs = " << NumArgsWithAttrs
<< ";\n";
499 OS
<< " AWI[NumAttrs] = AttributeWithIndex::get(~0, Attr);\n";
500 OS
<< " return AttrListPtr::get(AWI, NumAttrs+1);\n";
502 OS
<< "#endif // GET_INTRINSIC_ATTRIBUTES\n\n";
505 /// EmitModRefBehavior - Determine intrinsic alias analysis mod/ref behavior.
506 void IntrinsicEmitter::
507 EmitModRefBehavior(const std::vector
<CodeGenIntrinsic
> &Ints
, std::ostream
&OS
){
508 OS
<< "// Determine intrinsic alias analysis mod/ref behavior.\n";
509 OS
<< "#ifdef GET_INTRINSIC_MODREF_BEHAVIOR\n";
510 OS
<< "switch (id) {\n";
511 OS
<< "default:\n return UnknownModRefBehavior;\n";
512 for (unsigned i
= 0, e
= Ints
.size(); i
!= e
; ++i
) {
513 if (Ints
[i
].ModRef
== CodeGenIntrinsic::WriteMem
)
515 OS
<< "case " << TargetPrefix
<< "Intrinsic::" << Ints
[i
].EnumName
517 switch (Ints
[i
].ModRef
) {
519 assert(false && "Unknown Mod/Ref type!");
520 case CodeGenIntrinsic::NoMem
:
521 OS
<< " return DoesNotAccessMemory;\n";
523 case CodeGenIntrinsic::ReadArgMem
:
524 case CodeGenIntrinsic::ReadMem
:
525 OS
<< " return OnlyReadsMemory;\n";
527 case CodeGenIntrinsic::WriteArgMem
:
528 OS
<< " return AccessesArguments;\n";
533 OS
<< "#endif // GET_INTRINSIC_MODREF_BEHAVIOR\n\n";
536 void IntrinsicEmitter::
537 EmitGCCBuiltinList(const std::vector
<CodeGenIntrinsic
> &Ints
, std::ostream
&OS
){
538 OS
<< "// Get the GCC builtin that corresponds to an LLVM intrinsic.\n";
539 OS
<< "#ifdef GET_GCC_BUILTIN_NAME\n";
540 OS
<< " switch (F->getIntrinsicID()) {\n";
541 OS
<< " default: BuiltinName = \"\"; break;\n";
542 for (unsigned i
= 0, e
= Ints
.size(); i
!= e
; ++i
) {
543 if (!Ints
[i
].GCCBuiltinName
.empty()) {
544 OS
<< " case Intrinsic::" << Ints
[i
].EnumName
<< ": BuiltinName = \""
545 << Ints
[i
].GCCBuiltinName
<< "\"; break;\n";
552 /// EmitBuiltinComparisons - Emit comparisons to determine whether the specified
553 /// sorted range of builtin names is equal to the current builtin. This breaks
554 /// it down into a simple tree.
556 /// At this point, we know that all the builtins in the range have the same name
557 /// for the first 'CharStart' characters. Only the end of the name needs to be
559 typedef std::map
<std::string
, std::string
>::const_iterator StrMapIterator
;
560 static void EmitBuiltinComparisons(StrMapIterator Start
, StrMapIterator End
,
561 unsigned CharStart
, unsigned Indent
,
562 std::string TargetPrefix
, std::ostream
&OS
) {
563 if (Start
== End
) return; // empty range.
565 // Determine what, if anything, is the same about all these strings.
566 std::string CommonString
= Start
->first
;
567 unsigned NumInRange
= 0;
568 for (StrMapIterator I
= Start
; I
!= End
; ++I
, ++NumInRange
) {
569 // Find the first character that doesn't match.
570 const std::string
&ThisStr
= I
->first
;
571 unsigned NonMatchChar
= CharStart
;
572 while (NonMatchChar
< CommonString
.size() &&
573 NonMatchChar
< ThisStr
.size() &&
574 CommonString
[NonMatchChar
] == ThisStr
[NonMatchChar
])
576 // Truncate off pieces that don't match.
577 CommonString
.resize(NonMatchChar
);
580 // Just compare the rest of the string.
581 if (NumInRange
== 1) {
582 if (CharStart
!= CommonString
.size()) {
583 OS
<< std::string(Indent
*2, ' ') << "if (!memcmp(BuiltinName";
584 if (CharStart
) OS
<< "+" << CharStart
;
585 OS
<< ", \"" << (CommonString
.c_str()+CharStart
) << "\", ";
586 OS
<< CommonString
.size() - CharStart
<< "))\n";
589 OS
<< std::string(Indent
*2, ' ') << "IntrinsicID = " << TargetPrefix
591 OS
<< Start
->second
<< ";\n";
595 // At this point, we potentially have a common prefix for these builtins, emit
596 // a check for this common prefix.
597 if (CommonString
.size() != CharStart
) {
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";
603 EmitBuiltinComparisons(Start
, End
, CommonString
.size(), Indent
+1,
605 OS
<< std::string(Indent
*2, ' ') << "}\n";
609 // Output a switch on the character that differs across the set.
610 OS
<< std::string(Indent
*2, ' ') << "switch (BuiltinName[" << CharStart
613 OS
<< " // \"" << std::string(Start
->first
.begin(),
614 Start
->first
.begin()+CharStart
) << "\"";
617 for (StrMapIterator I
= Start
; I
!= End
; ) {
618 char ThisChar
= I
->first
[CharStart
];
619 OS
<< std::string(Indent
*2, ' ') << "case '" << ThisChar
<< "':\n";
620 // Figure out the range that has this common character.
621 StrMapIterator NextChar
= I
;
622 for (++NextChar
; NextChar
!= End
&& NextChar
->first
[CharStart
] == ThisChar
;
625 EmitBuiltinComparisons(I
, NextChar
, CharStart
+1, Indent
+1, TargetPrefix
,OS
);
626 OS
<< std::string(Indent
*2, ' ') << " break;\n";
629 OS
<< std::string(Indent
*2, ' ') << "}\n";
632 /// EmitTargetBuiltins - All of the builtins in the specified map are for the
633 /// same target, and we already checked it.
634 static void EmitTargetBuiltins(const std::map
<std::string
, std::string
> &BIM
,
635 const std::string
&TargetPrefix
,
637 // Rearrange the builtins by length.
638 std::vector
<std::map
<std::string
, std::string
> > BuiltinsByLen
;
639 BuiltinsByLen
.reserve(100);
641 for (StrMapIterator I
= BIM
.begin(), E
= BIM
.end(); I
!= E
; ++I
) {
642 if (I
->first
.size() >= BuiltinsByLen
.size())
643 BuiltinsByLen
.resize(I
->first
.size()+1);
644 BuiltinsByLen
[I
->first
.size()].insert(*I
);
647 // Now that we have all the builtins by their length, emit a switch stmt.
648 OS
<< " switch (strlen(BuiltinName)) {\n";
649 OS
<< " default: break;\n";
650 for (unsigned i
= 0, e
= BuiltinsByLen
.size(); i
!= e
; ++i
) {
651 if (BuiltinsByLen
[i
].empty()) continue;
652 OS
<< " case " << i
<< ":\n";
653 EmitBuiltinComparisons(BuiltinsByLen
[i
].begin(), BuiltinsByLen
[i
].end(),
654 0, 3, TargetPrefix
, OS
);
661 void IntrinsicEmitter::
662 EmitIntrinsicToGCCBuiltinMap(const std::vector
<CodeGenIntrinsic
> &Ints
,
664 typedef std::map
<std::string
, std::map
<std::string
, std::string
> > BIMTy
;
666 for (unsigned i
= 0, e
= Ints
.size(); i
!= e
; ++i
) {
667 if (!Ints
[i
].GCCBuiltinName
.empty()) {
668 // Get the map for this target prefix.
669 std::map
<std::string
, std::string
> &BIM
=BuiltinMap
[Ints
[i
].TargetPrefix
];
671 if (!BIM
.insert(std::make_pair(Ints
[i
].GCCBuiltinName
,
672 Ints
[i
].EnumName
)).second
)
673 throw "Intrinsic '" + Ints
[i
].TheDef
->getName() +
674 "': duplicate GCC builtin name!";
678 OS
<< "// Get the LLVM intrinsic that corresponds to a GCC builtin.\n";
679 OS
<< "// This is used by the C front-end. The GCC builtin name is passed\n";
680 OS
<< "// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed\n";
681 OS
<< "// in as TargetPrefix. The result is assigned to 'IntrinsicID'.\n";
682 OS
<< "#ifdef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN\n";
685 OS
<< "static " << TargetPrefix
<< "Intrinsic::ID "
686 << "getIntrinsicForGCCBuiltin(const char "
687 << "*TargetPrefix, const char *BuiltinName) {\n";
688 OS
<< " " << TargetPrefix
<< "Intrinsic::ID IntrinsicID = ";
690 OS
<< "Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char "
691 << "*TargetPrefix, const char *BuiltinName) {\n";
692 OS
<< " Intrinsic::ID IntrinsicID = ";
696 OS
<< "(" << TargetPrefix
<< "Intrinsic::ID)";
698 OS
<< "Intrinsic::not_intrinsic;\n";
700 // Note: this could emit significantly better code if we cared.
701 for (BIMTy::iterator I
= BuiltinMap
.begin(), E
= BuiltinMap
.end();I
!= E
;++I
){
703 if (!I
->first
.empty())
704 OS
<< "if (!strcmp(TargetPrefix, \"" << I
->first
<< "\")) ";
706 OS
<< "/* Target Independent Builtins */ ";
709 // Emit the comparisons for this target prefix.
710 EmitTargetBuiltins(I
->second
, TargetPrefix
, OS
);
713 OS
<< " return IntrinsicID;\n";