26 #define HAVE_PRINTF_A 1 27 #define ENABLE_CBE_PRINTF_A 1 36 #include "llvm/ADT/STLExtras.h" 37 #include "llvm/ADT/SmallString.h" 38 #include "llvm/ADT/StringExtras.h" 39 #include "llvm/Analysis/LoopInfo.h" 40 #include "llvm/Analysis/ValueTracking.h" 41 #include "llvm/CodeGen/IntrinsicLowering.h" 42 #include "llvm/CodeGen/Passes.h" 43 #include "llvm/IR/CFG.h" 44 #include "llvm/IR/CallSite.h" 45 #include "llvm/IR/CallingConv.h" 46 #include "llvm/IR/Constants.h" 47 #include "llvm/IR/DerivedTypes.h" 48 #include "llvm/IR/GetElementPtrTypeIterator.h" 49 #include "llvm/IR/InlineAsm.h" 50 #include "llvm/IR/InstIterator.h" 51 #include "llvm/IR/Instructions.h" 52 #include "llvm/IR/IntrinsicInst.h" 53 #include "llvm/IR/Intrinsics.h" 54 #include "llvm/IR/LegacyPassManager.h" 55 #include "llvm/IR/Module.h" 56 #include "llvm/IR/TypeFinder.h" 57 #include "llvm/IR/Verifier.h" 58 #include "llvm/InitializePasses.h" 59 #include "llvm/Pass.h" 60 #include "llvm/Support/FileSystem.h" 61 #include <llvm/IR/IRPrintingPasses.h> 63 #include "llvm/Transforms/Scalar.h" 64 #if ISPC_LLVM_VERSION >= ISPC_LLVM_7_0 65 #include "llvm/Transforms/Utils.h" 67 #include "llvm/IR/DataLayout.h" 68 #include "llvm/IR/InstVisitor.h" 69 #include "llvm/MC/MCAsmInfo.h" 70 #include "llvm/MC/MCContext.h" 71 #include "llvm/MC/MCInstrInfo.h" 72 #include "llvm/MC/MCObjectFileInfo.h" 73 #include "llvm/MC/MCRegisterInfo.h" 74 #include "llvm/MC/MCSubtargetInfo.h" 75 #include "llvm/MC/MCSymbol.h" 76 #include "llvm/Support/ErrorHandling.h" 77 #include "llvm/Support/FormattedStream.h" 78 #include "llvm/Support/Host.h" 79 #include "llvm/Support/MathExtras.h" 80 #include "llvm/Support/TargetRegistry.h" 81 #include "llvm/Target/TargetMachine.h" 83 #include <llvm/Support/ToolOutputFile.h> 84 #include <llvm/Transforms/IPO.h> 85 #include <llvm/Transforms/Utils/BasicBlockUtils.h> 86 #if ISPC_LLVM_VERSION >= ISPC_LLVM_8_0 87 #include "llvm/IR/PatternMatch.h" 89 #if ISPC_LLVM_VERSION >= ISPC_LLVM_10_0 90 #include "llvm/IR/IntrinsicsPowerPC.h" 91 #include "llvm/IR/IntrinsicsX86.h" 97 #define snprintf _snprintf 103 class constant_iterator :
public std::iterator<std::forward_iterator_tag, const llvm::Constant, ptrdiff_t> {
108 Assert(!InstI.atEnd() && OpIdx < InstI->getNumOperands() &&
"isAtConstant called with invalid arguments!");
109 return llvm::isa<llvm::Constant>(InstI->getOperand(OpIdx));
115 if (InstI != llvm::inst_end(F) &&
121 : InstI(
llvm::inst_end(F)), OpIdx(0) {}
128 return llvm::cast<llvm::Constant>(InstI->getOperand(OpIdx));
134 unsigned NumOperands = InstI->getNumOperands();
139 if (OpIdx < NumOperands)
143 }
while (!InstI.atEnd());
163 llvm::DenseSet<const llvm::Value *> VisitedConstants;
164 llvm::DenseSet<const llvm::Metadata *> VisitedMDNodes;
165 llvm::DenseSet<llvm::Type *> VisitedTypes;
166 std::vector<llvm::ArrayType *> &ArrayTypes;
167 std::vector<llvm::IntegerType *> &IntegerTypes;
168 std::vector<bool> &IsVolatile;
169 std::vector<int> &Alignment;
172 TypeFinder(std::vector<llvm::ArrayType *> &t, std::vector<llvm::IntegerType *> &i, std::vector<bool> &v,
174 : ArrayTypes(t), IntegerTypes(i), IsVolatile(v), Alignment(a) {}
176 void run(
const llvm::Module &M) {
178 for (llvm::Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) {
179 incorporateType(I->getType());
180 if (I->hasInitializer())
181 incorporateValue(I->getInitializer());
185 for (llvm::Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) {
186 incorporateType(I->getType());
187 if (
const llvm::Value *Aliasee = I->getAliasee())
188 incorporateValue(Aliasee);
191 llvm::SmallVector<std::pair<unsigned, llvm::MDNode *>, 4> MDForInst;
194 for (llvm::Module::const_iterator FI = M.begin(), E = M.end(); FI != E; ++FI) {
195 incorporateType(FI->getType());
197 for (llvm::Function::const_iterator BB = FI->begin(), E = FI->end(); BB != E; ++BB)
198 for (llvm::BasicBlock::const_iterator II = BB->begin(), E = BB->end(); II != E; ++II) {
199 const llvm::Instruction &I = *II;
204 if (llvm::isa<llvm::SwitchInst>(&I))
208 incorporateType(I.getType());
209 const llvm::StoreInst *St = llvm::dyn_cast<llvm::StoreInst>(&I);
211 if (llvm::IntegerType *ITy = llvm::dyn_cast<llvm::IntegerType>(I.getType())) {
212 IntegerTypes.push_back(ITy);
213 IsVolatile.push_back(St->isVolatile());
214 Alignment.push_back(St->getAlignment());
218 const llvm::LoadInst *Ld = llvm::dyn_cast<llvm::LoadInst>(&I);
220 if (llvm::IntegerType *ITy = llvm::dyn_cast<llvm::IntegerType>(I.getType())) {
221 IntegerTypes.push_back(ITy);
222 IsVolatile.push_back(Ld->isVolatile());
223 Alignment.push_back(Ld->getAlignment());
227 for (llvm::User::const_op_iterator OI = I.op_begin(), OE = I.op_end(); OI != OE; ++OI)
228 incorporateValue(*OI);
231 I.getAllMetadataOtherThanDebugLoc(MDForInst);
232 for (
unsigned i = 0, e = MDForInst.size(); i != e; ++i)
233 incorporateMDNode(MDForInst[i].second);
239 for (llvm::Module::const_named_metadata_iterator I = M.named_metadata_begin(), E = M.named_metadata_end();
241 const llvm::NamedMDNode *NMD = &*I;
242 for (
unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i)
243 incorporateMDNode(NMD->getOperand(i));
248 void incorporateType(llvm::Type *Ty) {
250 if (!VisitedTypes.insert(Ty).second)
253 if (llvm::ArrayType *ATy = llvm::dyn_cast<llvm::ArrayType>(Ty))
254 ArrayTypes.push_back(ATy);
257 for (llvm::Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); I != E; ++I)
265 void incorporateValue(
const llvm::Value *V) {
266 if (
const llvm::MetadataAsValue *MV = llvm::dyn_cast<llvm::MetadataAsValue>(V)) {
267 incorporateMDNode(MV->getMetadata());
270 if (!llvm::isa<llvm::Constant>(V) || llvm::isa<llvm::GlobalValue>(V))
274 if (!VisitedConstants.insert(V).second)
278 incorporateType(V->getType());
281 const llvm::User *U = llvm::cast<llvm::User>(V);
282 for (llvm::Constant::const_op_iterator I = U->op_begin(), E = U->op_end(); I != E; ++I)
283 incorporateValue(*I);
286 void incorporateMDNode(
const llvm::Metadata *M) {
289 if (!VisitedMDNodes.insert(M).second)
292 if (
const llvm::MDNode *N = llvm::dyn_cast<llvm::MDNode>(M)) {
294 for (
unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
295 if (
const llvm::Metadata *O = N->getOperand(i))
296 incorporateMDNode(O);
297 }
else if (llvm::isa<llvm::MDString>(M)) {
299 }
else if (
const llvm::ValueAsMetadata *V = llvm::dyn_cast<llvm::ValueAsMetadata>(M)) {
300 incorporateValue(V->getValue());
303 llvm_unreachable(
"Unknown Metadata subclass");
310 std::vector<llvm::IntegerType *> &i, std::vector<bool> &IsVolatile,
311 std::vector<int> &Alignment) {
312 TypeFinder(t, i, IsVolatile, Alignment).run(*m);
316 llvm::VectorType *VTy = llvm::dyn_cast<llvm::VectorType>(Ty);
317 if ((VTy != NULL) && (VTy->getElementType()->isIntegerTy()) &&
318 VTy->getElementType()->getPrimitiveSizeInBits() == 64)
324 class CBEMCAsmInfo :
public llvm::MCAsmInfo {
326 CBEMCAsmInfo() { PrivateGlobalPrefix =
""; }
331 class CWriter :
public llvm::FunctionPass,
public llvm::InstVisitor<CWriter> {
332 llvm::formatted_raw_ostream &Out;
333 llvm::IntrinsicLowering *IL;
336 const llvm::Module *TheModule;
337 const llvm::MCAsmInfo *TAsm;
338 const llvm::MCRegisterInfo *MRI;
339 const llvm::MCObjectFileInfo *MOFI;
340 llvm::MCContext *TCtx;
345 const llvm::DataLayout *TD;
347 std::map<const llvm::ConstantFP *, unsigned> FPConstantMap;
348 std::map<const llvm::ConstantDataVector *, unsigned> VectorConstantMap;
349 unsigned VectorConstantIndex;
350 std::set<llvm::Function *> intrinsicPrototypesAlreadyGenerated;
351 std::set<const llvm::Argument *> ByValParams;
353 unsigned OpaqueCounter;
354 llvm::DenseMap<const llvm::Value *, unsigned> AnonValueNumbers;
355 unsigned NextAnonValueNumber;
357 std::string includeName;
362 llvm::DenseMap<llvm::StructType *, unsigned> UnnamedStructIDs;
363 llvm::DenseMap<llvm::ArrayType *, unsigned> ArrayIDs;
367 explicit CWriter(llvm::formatted_raw_ostream &o,
const char *incname,
int vecwidth)
368 : FunctionPass(ID), Out(o), IL(0), LI(0), TheModule(0), TAsm(0), MRI(0), MOFI(0), TCtx(0), TD(0),
369 OpaqueCounter(0), NextAnonValueNumber(0), includeName(incname ? incname :
"generic_defs.h"),
370 vectorWidth(vecwidth) {
371 initializeLoopInfoWrapperPassPass(*llvm::PassRegistry::getPassRegistry());
373 VectorConstantIndex = 0;
376 virtual llvm::StringRef getPassName()
const {
return "C backend"; }
378 void getAnalysisUsage(llvm::AnalysisUsage &AU)
const {
379 AU.addRequired<llvm::LoopInfoWrapperPass>();
380 AU.setPreservesAll();
383 virtual bool doInitialization(llvm::Module &M);
385 bool runOnFunction(llvm::Function &F) {
388 if (F.hasAvailableExternallyLinkage())
391 LI = &getAnalysis<llvm::LoopInfoWrapperPass>().getLoopInfo();
397 printFloatingPointConstants(F);
401 printVectorConstants(F);
407 virtual bool doFinalization(llvm::Module &M) {
416 FPConstantMap.clear();
417 VectorConstantMap.clear();
419 intrinsicPrototypesAlreadyGenerated.clear();
420 UnnamedStructIDs.clear();
425 llvm::raw_ostream &printType(llvm::raw_ostream &Out, llvm::Type *Ty,
bool isSigned =
false,
426 const std::string &VariableName =
"",
bool IgnoreName =
false,
427 const llvm::AttributeList &PAL = llvm::AttributeList());
428 llvm::raw_ostream &printSimpleType(llvm::raw_ostream &Out, llvm::Type *Ty,
bool isSigned,
429 const std::string &NameSoFar =
"");
431 void printStructReturnPointerFunctionType(llvm::raw_ostream &Out,
const llvm::AttributeList &PAL,
432 llvm::PointerType *Ty);
434 std::string getStructName(llvm::StructType *ST);
435 std::string getArrayName(llvm::ArrayType *AT);
440 void writeOperandDeref(llvm::Value *Operand) {
441 if (isAddressExposed(Operand)) {
443 writeOperandInternal(Operand);
446 writeOperand(Operand);
451 void writeOperand(llvm::Value *Operand,
bool Static =
false);
452 void writeInstComputationInline(llvm::Instruction &I);
453 void writeOperandInternal(llvm::Value *Operand,
bool Static =
false);
454 void writeOperandWithCast(llvm::Value *Operand,
unsigned Opcode);
455 void writeOperandWithCast(llvm::Value *Operand,
const llvm::ICmpInst &I);
456 bool writeInstructionCast(
const llvm::Instruction &I);
458 void writeMemoryAccess(llvm::Value *Operand, llvm::Type *OperandType,
bool IsVolatile,
unsigned Alignment);
461 void lowerIntrinsics(llvm::Function &F);
464 void printIntrinsicDefinition(
const llvm::Function &F, llvm::raw_ostream &Out);
466 void printModuleTypes();
467 void printContainedStructs(llvm::Type *Ty, llvm::SmallPtrSet<llvm::Type *, 16> &);
468 void printContainedArrays(llvm::ArrayType *ATy, llvm::SmallPtrSet<llvm::Type *, 16> &);
469 void printFloatingPointConstants(llvm::Function &F);
470 void printFloatingPointConstants(
const llvm::Constant *C);
471 void printVectorConstants(llvm::Function &F);
472 void printFunctionSignature(
const llvm::Function *F,
bool Prototype);
474 void printFunction(llvm::Function &);
475 void printBasicBlock(llvm::BasicBlock *BB);
476 void printLoop(llvm::Loop *L);
478 bool printCast(
unsigned opcode, llvm::Type *SrcTy, llvm::Type *DstTy);
479 void printConstant(llvm::Constant *CPV,
bool Static);
480 void printConstantWithCast(llvm::Constant *CPV,
unsigned Opcode);
481 bool printConstExprCast(
const llvm::ConstantExpr *CE,
bool Static);
482 void printConstantArray(llvm::ConstantArray *CPA,
bool Static);
483 void printConstantVector(llvm::ConstantVector *CV,
bool Static);
484 void printConstantDataSequential(llvm::ConstantDataSequential *CDS,
bool Static);
489 bool isAddressExposed(
const llvm::Value *V)
const {
490 if (
const llvm::Argument *A = llvm::dyn_cast<llvm::Argument>(V))
491 return ByValParams.count(A);
492 return llvm::isa<llvm::GlobalVariable>(V) || isDirectAlloca(V);
500 static bool isInlinableInst(
const llvm::Instruction &I) {
503 if (llvm::isa<llvm::CmpInst>(I) && llvm::isa<llvm::VectorType>(I.getType()) ==
false)
507 if (llvm::isa<llvm::AtomicCmpXchgInst>(I))
512 if (I.getType() == llvm::Type::getVoidTy(I.getContext()) || !I.hasOneUse() ||
513 #if ISPC_LLVM_VERSION >= ISPC_LLVM_8_0 // 8.0+ 516 llvm::isa<llvm::TerminatorInst>(I)
518 || llvm::isa<llvm::CallInst>(I) || llvm::isa<llvm::PHINode>(I) || llvm::isa<llvm::LoadInst>(I) ||
519 llvm::isa<llvm::VAArgInst>(I) || llvm::isa<llvm::InsertElementInst>(I) ||
520 llvm::isa<llvm::InsertValueInst>(I) || llvm::isa<llvm::ExtractValueInst>(I) ||
521 llvm::isa<llvm::SelectInst>(I))
528 const llvm::Instruction &User = llvm::cast<llvm::Instruction>(*I.user_back());
529 if (isInlineAsm(User) || llvm::isa<llvm::ExtractElementInst>(User) ||
530 llvm::isa<llvm::ShuffleVectorInst>(User) || llvm::isa<llvm::AtomicRMWInst>(User) ||
531 llvm::isa<llvm::AtomicCmpXchgInst>(User))
536 return I.getParent() == llvm::cast<llvm::Instruction>(I.user_back())->getParent();
543 static const llvm::AllocaInst *isDirectAlloca(
const llvm::Value *V) {
544 const llvm::AllocaInst *AI = llvm::dyn_cast<llvm::AllocaInst>(V);
547 if (AI->isArrayAllocation())
549 if (AI->getParent() != &AI->getParent()->getParent()->getEntryBlock())
555 static bool isInlineAsm(
const llvm::Instruction &I) {
556 if (
const llvm::CallInst *CI = llvm::dyn_cast<llvm::CallInst>(&I))
557 return llvm::isa<llvm::InlineAsm>(CI->getCalledValue());
562 friend class llvm::InstVisitor<CWriter>;
564 void visitReturnInst(llvm::ReturnInst &I);
565 void visitBranchInst(llvm::BranchInst &I);
566 void visitSwitchInst(llvm::SwitchInst &I);
567 void visitIndirectBrInst(llvm::IndirectBrInst &I);
568 void visitInvokeInst(llvm::InvokeInst &I) { llvm_unreachable(
"Lowerinvoke pass didn't work!"); }
569 void visitResumeInst(llvm::ResumeInst &I) { llvm_unreachable(
"DwarfEHPrepare pass didn't work!"); }
570 void visitUnreachableInst(llvm::UnreachableInst &I);
572 void visitPHINode(llvm::PHINode &I);
573 void visitBinaryOperator(llvm::Instruction &I);
574 void visitICmpInst(llvm::ICmpInst &I);
575 void visitFCmpInst(llvm::FCmpInst &I);
577 void visitCastInst(llvm::CastInst &I);
578 void visitSelectInst(llvm::SelectInst &I);
579 void visitCallInst(llvm::CallInst &I);
580 void visitInlineAsm(llvm::CallInst &I);
581 bool visitBuiltinCall(llvm::CallInst &I, llvm::Intrinsic::ID ID,
bool &WroteCallee);
583 void visitAllocaInst(llvm::AllocaInst &I);
584 void visitLoadInst(llvm::LoadInst &I);
585 void visitStoreInst(llvm::StoreInst &I);
586 void visitGetElementPtrInst(llvm::GetElementPtrInst &I);
587 void visitVAArgInst(llvm::VAArgInst &I);
589 void visitInsertElementInst(llvm::InsertElementInst &I);
590 void visitExtractElementInst(llvm::ExtractElementInst &I);
591 void visitShuffleVectorInst(llvm::ShuffleVectorInst &SVI);
593 void visitInsertValueInst(llvm::InsertValueInst &I);
594 void visitExtractValueInst(llvm::ExtractValueInst &I);
596 void visitAtomicRMWInst(llvm::AtomicRMWInst &I);
597 void visitAtomicCmpXchgInst(llvm::AtomicCmpXchgInst &I);
599 void visitInstruction(llvm::Instruction &I) {
601 llvm::errs() <<
"C Writer does not know about " << I;
606 void outputLValue(llvm::Instruction *I) { Out <<
" " << GetValueName(I) <<
" = "; }
608 bool isGotoCodeNecessary(llvm::BasicBlock *From, llvm::BasicBlock *To);
609 void printPHICopiesForSuccessor(llvm::BasicBlock *CurBlock, llvm::BasicBlock *Successor,
unsigned Indent);
610 void printBranchToBlock(llvm::BasicBlock *CurBlock, llvm::BasicBlock *SuccBlock,
unsigned Indent);
611 void printGEPExpression(llvm::Value *Ptr, llvm::gep_type_iterator I, llvm::gep_type_iterator E,
bool Static);
613 std::string GetValueName(
const llvm::Value *Operand);
617 char CWriter::ID = 0;
622 for (
unsigned i = 0, e = S.size(); i != e; ++i) {
623 if (i + 1 != e && ((S[i] ==
'>' && S[i + 1] ==
'>') || (S[i] ==
'<' && S[i + 1] ==
'<'))) {
625 Result +=
'A' + (S[i] & 15);
626 Result +=
'A' + ((S[i] >> 4) & 15);
629 }
else if (isalnum(S[i]) || S[i] ==
'_' || S[i] ==
'<' || S[i] ==
'>') {
633 Result +=
'A' + (S[i] & 15);
634 Result +=
'A' + ((S[i] >> 4) & 15);
641 std::string CWriter::getStructName(llvm::StructType *ST) {
642 if (!ST->isLiteral() && !ST->getName().empty())
643 return CBEMangle(
"l_" + ST->getName().str());
645 return "l_unnamed_" + llvm::utostr(UnnamedStructIDs[ST]);
648 std::string CWriter::getArrayName(llvm::ArrayType *AT) {
return "l_array_" + llvm::utostr(ArrayIDs[AT]); }
653 void CWriter::printStructReturnPointerFunctionType(llvm::raw_ostream &Out,
const llvm::AttributeList &PAL,
654 llvm::PointerType *TheTy) {
655 llvm::FunctionType *FTy = llvm::cast<llvm::FunctionType>(TheTy->getElementType());
657 llvm::raw_string_ostream FunctionInnards(tstr);
658 FunctionInnards <<
" (*) (";
659 bool PrintedType =
false;
661 llvm::FunctionType::param_iterator I = FTy->param_begin(), E = FTy->param_end();
662 llvm::Type *RetTy = llvm::cast<llvm::PointerType>(*I)->getElementType();
664 for (++I, ++Idx; I != E; ++I, ++Idx) {
666 FunctionInnards <<
", ";
667 llvm::Type *ArgTy = *I;
668 if (PAL.getParamAttributes(Idx).hasAttribute(llvm::Attribute::ByVal)) {
669 Assert(ArgTy->isPointerTy());
670 ArgTy = llvm::cast<llvm::PointerType>(ArgTy)->getElementType();
672 printType(FunctionInnards, ArgTy, PAL.getParamAttributes(Idx).hasAttribute(llvm::Attribute::SExt),
"");
675 if (FTy->isVarArg()) {
677 FunctionInnards <<
" int";
678 FunctionInnards <<
", ...";
679 }
else if (!PrintedType) {
680 FunctionInnards <<
"void";
682 FunctionInnards <<
')';
683 printType(Out, RetTy, PAL.getParamAttributes(0).hasAttribute(llvm::Attribute::SExt), FunctionInnards.str());
686 llvm::raw_ostream &CWriter::printSimpleType(llvm::raw_ostream &Out, llvm::Type *Ty,
bool isSigned,
687 const std::string &NameSoFar) {
688 Assert((Ty->isFloatingPointTy() || Ty->isX86_MMXTy() || Ty->isIntegerTy() || Ty->isVectorTy() || Ty->isVoidTy()) &&
689 "Invalid type for printSimpleType");
690 switch (Ty->getTypeID()) {
691 case llvm::Type::VoidTyID:
692 return Out <<
"void " << NameSoFar;
693 case llvm::Type::IntegerTyID: {
694 unsigned NumBits = llvm::cast<llvm::IntegerType>(Ty)->getBitWidth();
696 return Out <<
"bool " << NameSoFar;
697 else if (NumBits <= 8)
698 return Out << (isSigned ?
"" :
"u") <<
"int8_t " << NameSoFar;
699 else if (NumBits <= 16)
700 return Out << (isSigned ?
"" :
"u") <<
"int16_t " << NameSoFar;
701 else if (NumBits <= 32)
702 return Out << (isSigned ?
"" :
"u") <<
"int32_t " << NameSoFar;
703 else if (NumBits <= 64)
704 return Out << (isSigned ?
"" :
"u") <<
"int64_t " << NameSoFar;
706 return Out <<
"iN<" << NumBits <<
"> " << NameSoFar;
708 case llvm::Type::FloatTyID:
709 return Out <<
"float " << NameSoFar;
710 case llvm::Type::DoubleTyID:
711 return Out <<
"double " << NameSoFar;
714 case llvm::Type::X86_FP80TyID:
715 case llvm::Type::PPC_FP128TyID:
716 case llvm::Type::FP128TyID:
717 return Out <<
"long double " << NameSoFar;
719 case llvm::Type::X86_MMXTyID:
720 return printSimpleType(Out, llvm::Type::getInt32Ty(Ty->getContext()), isSigned,
721 " __attribute__((vector_size(64))) " + NameSoFar);
723 case llvm::Type::VectorTyID: {
724 llvm::VectorType *VTy = llvm::cast<llvm::VectorType>(Ty);
726 const char *suffix = NULL;
727 const llvm::Type *eltTy = VTy->getElementType();
728 if (eltTy->isFloatTy())
730 else if (eltTy->isDoubleTy())
733 Assert(eltTy->isIntegerTy());
734 switch (eltTy->getPrimitiveSizeInBits()) {
756 return Out <<
"__vec" << VTy->getNumElements() <<
"_" << suffix <<
" " << NameSoFar;
758 return printSimpleType(Out, VTy->getElementType(), isSigned,
759 " __attribute__((vector_size(" + utostr(TD->getTypeAllocSize(VTy)) +
" ))) " +
766 llvm::errs() <<
"Unknown primitive type: " << *Ty <<
"\n";
776 llvm::raw_ostream &CWriter::printType(llvm::raw_ostream &Out, llvm::Type *Ty,
bool isSigned,
777 const std::string &NameSoFar,
bool IgnoreName,
const llvm::AttributeList &PAL) {
779 if (Ty->isFloatingPointTy() || Ty->isX86_MMXTy() || Ty->isIntegerTy() || Ty->isVectorTy() || Ty->isVoidTy()) {
780 printSimpleType(Out, Ty, isSigned, NameSoFar);
784 switch (Ty->getTypeID()) {
785 case llvm::Type::FunctionTyID: {
786 llvm::FunctionType *FTy = llvm::cast<llvm::FunctionType>(Ty);
788 llvm::raw_string_ostream FunctionInnards(tstr);
789 FunctionInnards <<
" (" << NameSoFar <<
") (";
791 for (llvm::FunctionType::param_iterator I = FTy->param_begin(), E = FTy->param_end(); I != E; ++I) {
792 llvm::Type *ArgTy = *I;
793 if (PAL.getParamAttributes(Idx).hasAttribute(llvm::Attribute::ByVal)) {
794 Assert(ArgTy->isPointerTy());
795 ArgTy = llvm::cast<llvm::PointerType>(ArgTy)->getElementType();
797 if (I != FTy->param_begin())
798 FunctionInnards <<
", ";
799 printType(FunctionInnards, ArgTy, PAL.getParamAttributes(Idx).hasAttribute(llvm::Attribute::SExt),
"");
802 if (FTy->isVarArg()) {
803 if (!FTy->getNumParams())
804 FunctionInnards <<
" int";
805 FunctionInnards <<
", ...";
806 }
else if (!FTy->getNumParams()) {
807 FunctionInnards <<
"void";
809 FunctionInnards <<
')';
810 printType(Out, FTy->getReturnType(), PAL.getParamAttributes(0).hasAttribute(llvm::Attribute::SExt),
811 FunctionInnards.str());
814 case llvm::Type::StructTyID: {
815 llvm::StructType *STy = llvm::cast<llvm::StructType>(Ty);
819 return Out << getStructName(STy) <<
' ' << NameSoFar;
821 Out <<
"struct " << NameSoFar <<
" {\n";
824 if (STy->getNumElements() > 0) {
825 Out <<
" static " << NameSoFar <<
" init(";
827 for (llvm::StructType::element_iterator I = STy->element_begin(), E = STy->element_end(); I != E;
830 snprintf(buf,
sizeof(buf),
"v%d", Idx);
831 printType(Out, *I,
false, buf);
832 if (Idx + 1 < STy->getNumElements())
836 Out <<
" " << NameSoFar <<
" ret;\n";
837 for (Idx = 0; Idx < STy->getNumElements(); ++Idx)
838 Out <<
" ret.field" << Idx <<
" = v" << Idx <<
";\n";
839 Out <<
" return ret;\n";
844 for (llvm::StructType::element_iterator I = STy->element_begin(), E = STy->element_end(); I != E; ++I) {
846 printType(Out, *I,
false,
"field" + llvm::utostr(Idx++));
851 Out <<
" __attribute__ ((packed))";
855 case llvm::Type::PointerTyID: {
856 llvm::PointerType *PTy = llvm::cast<llvm::PointerType>(Ty);
857 std::string ptrName =
"*" + NameSoFar;
859 if (PTy->getElementType()->isArrayTy() || PTy->getElementType()->isVectorTy())
860 ptrName =
"(" + ptrName +
")";
864 return printType(Out, PTy->getElementType(),
false, ptrName,
true, PAL);
865 return printType(Out, PTy->getElementType(),
false, ptrName);
868 case llvm::Type::ArrayTyID: {
869 llvm::ArrayType *ATy = llvm::cast<llvm::ArrayType>(Ty);
873 return Out << getArrayName(ATy) <<
' ' << NameSoFar;
875 unsigned NumElements = (unsigned)ATy->getNumElements();
876 if (NumElements == 0)
880 Out <<
"struct " << NameSoFar <<
" {\n";
882 Out <<
" static " << NameSoFar <<
" init(";
883 for (
unsigned Idx = 0; Idx < NumElements; ++Idx) {
885 snprintf(buf,
sizeof(buf),
"v%d", Idx);
886 printType(Out, ATy->getElementType(),
false, buf);
887 if (Idx + 1 < NumElements)
891 Out <<
" " << NameSoFar <<
" ret;\n";
892 for (
unsigned Idx = 0; Idx < NumElements; ++Idx)
893 Out <<
" ret.array[" << Idx <<
"] = v" << Idx <<
";\n";
894 Out <<
" return ret;\n";
900 Out <<
" static " << NameSoFar <<
" init(const char *p) {\n";
901 Out <<
" " << NameSoFar <<
" ret;\n";
902 Out <<
" memcpy((uint8_t *)ret.array, (uint8_t *)p, " << NumElements <<
");\n";
903 Out <<
" return ret;\n";
907 printType(Out, ATy->getElementType(),
false,
"array[" + llvm::utostr(NumElements) +
"]");
908 return Out <<
";\n} ";
912 llvm_unreachable(
"Unhandled case in getTypeProps!");
917 void CWriter::printConstantArray(llvm::ConstantArray *CPA,
bool Static) {
921 Out <<
"/* vec16_i64 should be loaded carefully on knc */";
922 Out <<
"\n#if defined(KNC)\n";
927 printConstant(llvm::cast<llvm::Constant>(CPA->getOperand(0)), Static);
930 for (
unsigned i = 1, e = CPA->getNumOperands(); i != e; ++i) {
934 Out <<
"/* vec16_i64 should be loaded carefully on knc */";
935 Out <<
"\n#if defined(KNC) \n";
937 Out <<
"\n#endif \n";
940 printConstant(llvm::cast<llvm::Constant>(CPA->getOperand(i)), Static);
945 void CWriter::printConstantVector(llvm::ConstantVector *CP,
bool Static) {
946 printConstant(llvm::cast<llvm::Constant>(CP->getOperand(0)), Static);
947 for (
unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) {
949 printConstant(llvm::cast<llvm::Constant>(CP->getOperand(i)), Static);
953 void CWriter::printConstantDataSequential(llvm::ConstantDataSequential *CDS,
bool Static) {
957 if (CDS->isCString()) {
960 bool LastWasHex =
false;
962 llvm::StringRef Bytes = CDS->getAsCString();
965 for (
unsigned i = 0, e = Bytes.size(); i != e; ++i) {
966 unsigned char C = Bytes[i];
974 if (isprint(C) && (!LastWasHex || !isxdigit(C))) {
976 if (C ==
'"' || C ==
'\\')
977 Out <<
"\\" << (char)C;
1006 Out << (char)((C / 16 < 10) ? (C / 16 +
'0') : (C / 16 - 10 +
'A'));
1007 Out << (char)(((C & 15) < 10) ? ((C & 15) +
'0') : ((C & 15) - 10 +
'A'));
1015 printConstant(CDS->getElementAsConstant(0), Static);
1016 for (
unsigned i = 1, e = CDS->getNumElements(); i != e; ++i) {
1018 printConstant(CDS->getElementAsConstant(i), Static);
1023 static inline std::string
ftostr(
const llvm::APFloat &V) {
1025 if (&V.getSemantics() == &llvm::APFloat::IEEEdouble()) {
1026 llvm::raw_string_ostream(Buf) << V.convertToDouble();
1028 }
else if (&V.getSemantics() == &llvm::APFloat::IEEEsingle()) {
1029 llvm::raw_string_ostream(Buf) << (double)V.convertToFloat();
1032 return "<unknown format in ftostr>";
1046 if (CFP->getType() != llvm::Type::getFloatTy(CFP->getContext()) &&
1047 CFP->getType() != llvm::Type::getDoubleTy(CFP->getContext()))
1049 llvm::APFloat APF = llvm::APFloat(CFP->getValueAPF());
1050 if (CFP->getType() == llvm::Type::getFloatTy(CFP->getContext()))
1051 APF.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven, &ignored);
1052 #if HAVE_PRINTF_A && ENABLE_CBE_PRINTF_A 1054 snprintf(Buffer,
sizeof(Buffer),
"%a", APF.convertToDouble());
1055 if (!strncmp(Buffer,
"0x", 2) || !strncmp(Buffer,
"-0x", 3) || !strncmp(Buffer,
"+0x", 3))
1056 return APF.bitwiseIsEqual(llvm::APFloat(atof(Buffer)));
1059 std::string StrVal =
ftostr(APF);
1061 while (StrVal[0] ==
' ')
1062 StrVal.erase(StrVal.begin());
1066 if ((StrVal[0] >=
'0' && StrVal[0] <=
'9') ||
1067 ((StrVal[0] ==
'-' || StrVal[0] ==
'+') && (StrVal[1] >=
'0' && StrVal[1] <=
'9')))
1069 return APF.bitwiseIsEqual(llvm::APFloat(atof(StrVal.c_str())));
1078 bool CWriter::printCast(
unsigned opc, llvm::Type *SrcTy, llvm::Type *DstTy) {
1079 if (llvm::isa<const llvm::VectorType>(DstTy)) {
1080 Assert(llvm::isa<const llvm::VectorType>(SrcTy));
1082 case llvm::Instruction::UIToFP:
1083 Out <<
"__cast_uitofp(";
1085 case llvm::Instruction::SIToFP:
1086 Out <<
"__cast_sitofp(";
1088 case llvm::Instruction::IntToPtr:
1089 llvm_unreachable(
"Invalid vector cast");
1090 case llvm::Instruction::Trunc:
1091 Out <<
"__cast_trunc(";
1093 case llvm::Instruction::BitCast:
1094 Out <<
"__cast_bits(";
1096 case llvm::Instruction::FPExt:
1097 Out <<
"__cast_fpext(";
1099 case llvm::Instruction::FPTrunc:
1100 Out <<
"__cast_fptrunc(";
1102 case llvm::Instruction::ZExt:
1103 Out <<
"__cast_zext(";
1105 case llvm::Instruction::PtrToInt:
1106 llvm_unreachable(
"Invalid vector cast");
1107 case llvm::Instruction::FPToUI:
1108 Out <<
"__cast_fptoui(";
1110 case llvm::Instruction::SExt:
1111 Out <<
"__cast_sext(";
1113 case llvm::Instruction::FPToSI:
1114 Out <<
"__cast_fptosi(";
1117 llvm_unreachable(
"Invalid cast opcode");
1123 printType(Out, DstTy);
1131 case llvm::Instruction::BitCast: {
1132 if (DstTy->isPointerTy()) {
1134 printType(Out, DstTy);
1138 Out <<
"__cast_bits((";
1139 printType(Out, DstTy);
1144 case llvm::Instruction::UIToFP:
1145 case llvm::Instruction::SIToFP:
1146 case llvm::Instruction::IntToPtr:
1147 case llvm::Instruction::Trunc:
1148 case llvm::Instruction::FPExt:
1149 case llvm::Instruction::FPTrunc:
1151 printType(Out, DstTy);
1154 case llvm::Instruction::ZExt:
1155 case llvm::Instruction::PtrToInt:
1156 case llvm::Instruction::FPToUI:
1158 printSimpleType(Out, DstTy,
false);
1161 case llvm::Instruction::SExt:
1162 case llvm::Instruction::FPToSI:
1164 printSimpleType(Out, DstTy,
true);
1168 llvm_unreachable(
"Invalid cast opcode");
1173 case llvm::Instruction::UIToFP:
1174 case llvm::Instruction::ZExt:
1176 printSimpleType(Out, SrcTy,
false);
1179 case llvm::Instruction::SIToFP:
1180 case llvm::Instruction::SExt:
1182 printSimpleType(Out, SrcTy,
true);
1185 case llvm::Instruction::IntToPtr:
1186 case llvm::Instruction::PtrToInt:
1188 Out <<
"(unsigned long)";
1190 case llvm::Instruction::Trunc:
1191 case llvm::Instruction::BitCast:
1192 case llvm::Instruction::FPExt:
1193 case llvm::Instruction::FPTrunc:
1194 case llvm::Instruction::FPToSI:
1195 case llvm::Instruction::FPToUI:
1198 llvm_unreachable(
"Invalid cast opcode");
1209 static const char *
lGetTypedFunc(
const char *base, llvm::Type *matchType,
int width) {
1210 static const char *ty_desc_str[] = {
"f",
"d",
"i1",
"i8",
"i16",
"i32",
"i64"};
1211 static const char *fn_desc_str[] = {
"float",
"double",
"i1",
"i8",
"i16",
"i32",
"i64"};
1212 enum { DESC_FLOAT, DESC_DOUBLE, DESC_I1, DESC_I8, DESC_I16, DESC_I32, DESC_I64 } desc;
1214 switch (matchType->getTypeID()) {
1215 case llvm::Type::FloatTyID:
1218 case llvm::Type::DoubleTyID:
1221 case llvm::Type::IntegerTyID: {
1222 switch (llvm::cast<llvm::IntegerType>(matchType)->getBitWidth()) {
1248 snprintf(buf, 64,
"__%s_%s<__vec%d_%s>", base, fn_desc_str[desc], width, ty_desc_str[desc]);
1253 void CWriter::printConstant(llvm::Constant *CPV,
bool Static) {
1254 if (
const llvm::ConstantExpr *CE = llvm::dyn_cast<llvm::ConstantExpr>(CPV)) {
1255 if (llvm::isa<llvm::VectorType>(CPV->getType())) {
1256 Assert(CE->getOpcode() == llvm::Instruction::BitCast);
1257 llvm::ConstantExpr *Op = llvm::dyn_cast<llvm::ConstantExpr>(CE->getOperand(0));
1258 Assert(Op && Op->getOpcode() == llvm::Instruction::BitCast);
1259 Assert(llvm::isa<llvm::VectorType>(Op->getOperand(0)->getType()));
1261 Out <<
"(__cast_bits(";
1262 printType(Out, CE->getType());
1264 printConstant(Op->getOperand(0), Static);
1268 switch (CE->getOpcode()) {
1269 case llvm::Instruction::Trunc:
1270 case llvm::Instruction::ZExt:
1271 case llvm::Instruction::SExt:
1272 case llvm::Instruction::FPTrunc:
1273 case llvm::Instruction::FPExt:
1274 case llvm::Instruction::UIToFP:
1275 case llvm::Instruction::SIToFP:
1276 case llvm::Instruction::FPToUI:
1277 case llvm::Instruction::FPToSI:
1278 case llvm::Instruction::PtrToInt:
1279 case llvm::Instruction::IntToPtr:
1280 case llvm::Instruction::BitCast: {
1281 if (CE->getOpcode() == llvm::Instruction::BitCast && CE->getType()->isPointerTy() ==
false) {
1282 Out <<
"__cast_bits((";
1283 printType(Out, CE->getType());
1285 printConstant(CE->getOperand(0), Static);
1291 bool closeParen = printCast(CE->getOpcode(), CE->getOperand(0)->getType(), CE->getType());
1292 if (CE->getOpcode() == llvm::Instruction::SExt &&
1293 CE->getOperand(0)->getType() == llvm::Type::getInt1Ty(CPV->getContext())) {
1297 printConstant(CE->getOperand(0), Static);
1298 if (CE->getType() == llvm::Type::getInt1Ty(CPV->getContext()) &&
1299 (CE->getOpcode() == llvm::Instruction::Trunc || CE->getOpcode() == llvm::Instruction::FPToUI ||
1300 CE->getOpcode() == llvm::Instruction::FPToSI || CE->getOpcode() == llvm::Instruction::PtrToInt)) {
1309 case llvm::Instruction::GetElementPtr:
1310 Assert(!llvm::isa<llvm::VectorType>(CPV->getType()));
1312 printGEPExpression(CE->getOperand(0), gep_type_begin(CPV), gep_type_end(CPV), Static);
1315 case llvm::Instruction::Select:
1316 Assert(!llvm::isa<llvm::VectorType>(CPV->getType()));
1318 printConstant(CE->getOperand(0), Static);
1320 printConstant(CE->getOperand(1), Static);
1322 printConstant(CE->getOperand(2), Static);
1325 case llvm::Instruction::Add:
1326 case llvm::Instruction::FAdd:
1327 case llvm::Instruction::Sub:
1328 case llvm::Instruction::FSub:
1329 case llvm::Instruction::Mul:
1330 case llvm::Instruction::FMul:
1331 case llvm::Instruction::SDiv:
1332 case llvm::Instruction::UDiv:
1333 case llvm::Instruction::FDiv:
1334 case llvm::Instruction::URem:
1335 case llvm::Instruction::SRem:
1336 case llvm::Instruction::FRem:
1337 case llvm::Instruction::And:
1338 case llvm::Instruction::Or:
1339 case llvm::Instruction::Xor:
1340 case llvm::Instruction::ICmp:
1341 case llvm::Instruction::Shl:
1342 case llvm::Instruction::LShr:
1343 case llvm::Instruction::AShr: {
1344 Assert(!llvm::isa<llvm::VectorType>(CPV->getType()));
1346 bool NeedsClosingParens = printConstExprCast(CE, Static);
1347 printConstantWithCast(CE->getOperand(0), CE->getOpcode());
1348 switch (CE->getOpcode()) {
1349 case llvm::Instruction::Add:
1350 case llvm::Instruction::FAdd:
1353 case llvm::Instruction::Sub:
1354 case llvm::Instruction::FSub:
1357 case llvm::Instruction::Mul:
1358 case llvm::Instruction::FMul:
1361 case llvm::Instruction::URem:
1362 case llvm::Instruction::SRem:
1363 case llvm::Instruction::FRem:
1366 case llvm::Instruction::UDiv:
1367 case llvm::Instruction::SDiv:
1368 case llvm::Instruction::FDiv:
1371 case llvm::Instruction::And:
1374 case llvm::Instruction::Or:
1377 case llvm::Instruction::Xor:
1380 case llvm::Instruction::Shl:
1383 case llvm::Instruction::LShr:
1384 case llvm::Instruction::AShr:
1387 case llvm::Instruction::ICmp:
1388 switch (CE->getPredicate()) {
1389 case llvm::ICmpInst::ICMP_EQ:
1392 case llvm::ICmpInst::ICMP_NE:
1395 case llvm::ICmpInst::ICMP_SLT:
1396 case llvm::ICmpInst::ICMP_ULT:
1399 case llvm::ICmpInst::ICMP_SLE:
1400 case llvm::ICmpInst::ICMP_ULE:
1403 case llvm::ICmpInst::ICMP_SGT:
1404 case llvm::ICmpInst::ICMP_UGT:
1407 case llvm::ICmpInst::ICMP_SGE:
1408 case llvm::ICmpInst::ICMP_UGE:
1412 llvm_unreachable(
"Illegal ICmp predicate");
1416 llvm_unreachable(
"Illegal opcode here!");
1418 printConstantWithCast(CE->getOperand(1), CE->getOpcode());
1419 if (NeedsClosingParens)
1424 case llvm::Instruction::FCmp: {
1425 Assert(!llvm::isa<llvm::VectorType>(CPV->getType()));
1427 bool NeedsClosingParens = printConstExprCast(CE, Static);
1428 if (CE->getPredicate() == llvm::FCmpInst::FCMP_FALSE)
1430 else if (CE->getPredicate() == llvm::FCmpInst::FCMP_TRUE)
1434 switch (CE->getPredicate()) {
1436 llvm_unreachable(
"Illegal FCmp predicate");
1437 case llvm::FCmpInst::FCMP_ORD:
1440 case llvm::FCmpInst::FCMP_UNO:
1443 case llvm::FCmpInst::FCMP_UEQ:
1446 case llvm::FCmpInst::FCMP_UNE:
1449 case llvm::FCmpInst::FCMP_ULT:
1452 case llvm::FCmpInst::FCMP_ULE:
1455 case llvm::FCmpInst::FCMP_UGT:
1458 case llvm::FCmpInst::FCMP_UGE:
1461 case llvm::FCmpInst::FCMP_OEQ:
1464 case llvm::FCmpInst::FCMP_ONE:
1467 case llvm::FCmpInst::FCMP_OLT:
1470 case llvm::FCmpInst::FCMP_OLE:
1473 case llvm::FCmpInst::FCMP_OGT:
1476 case llvm::FCmpInst::FCMP_OGE:
1480 Out <<
"llvm_fcmp_" << op <<
"(";
1481 printConstantWithCast(CE->getOperand(0), CE->getOpcode());
1483 printConstantWithCast(CE->getOperand(1), CE->getOpcode());
1486 if (NeedsClosingParens)
1493 llvm::errs() <<
"CWriter Error: Unhandled constant expression: " << *CE <<
"\n";
1495 llvm_unreachable(0);
1497 }
else if (llvm::isa<llvm::UndefValue>(CPV) && CPV->getType()->isSingleValueType()) {
1498 if (CPV->getType()->isVectorTy()) {
1499 printType(Out, CPV->getType());
1500 Out <<
"( /* UNDEF */)";
1505 printType(Out, CPV->getType());
1506 Out <<
")/*UNDEF*/";
1511 if (llvm::ConstantInt *CI = llvm::dyn_cast<llvm::ConstantInt>(CPV)) {
1512 llvm::Type *Ty = CI->getType();
1513 if (Ty == llvm::Type::getInt1Ty(CPV->getContext()))
1514 Out << (CI->getZExtValue() ?
'1' :
'0');
1515 else if (Ty == llvm::Type::getInt32Ty(CPV->getContext()))
1516 Out << CI->getZExtValue() <<
'u';
1517 else if (Ty == llvm::Type::getInt64Ty(CPV->getContext()))
1518 Out << CI->getZExtValue() <<
"ull";
1519 else if (Ty->getPrimitiveSizeInBits() > 64) {
1522 const uint64_t *Ptr64 = CI->getValue().getRawData();
1523 for (
unsigned i = 0; i < Ty->getPrimitiveSizeInBits(); i++) {
1524 Out << ((Ptr64[i / (
sizeof(uint64_t) * 8)] >> (i % (
sizeof(uint64_t) * 8))) & 1);
1529 printSimpleType(Out, Ty,
false) <<
')';
1530 if (CI->isMinValue(
true))
1531 Out << CI->getZExtValue() <<
'u';
1533 Out << CI->getSExtValue();
1539 switch (CPV->getType()->getTypeID()) {
1540 case llvm::Type::FloatTyID:
1541 case llvm::Type::DoubleTyID:
1542 case llvm::Type::X86_FP80TyID:
1543 case llvm::Type::PPC_FP128TyID:
1544 case llvm::Type::FP128TyID: {
1545 llvm::ConstantFP *FPC = llvm::cast<llvm::ConstantFP>(CPV);
1546 std::map<const llvm::ConstantFP *, unsigned>::iterator I = FPConstantMap.find(FPC);
1547 if (I != FPConstantMap.end()) {
1551 << (FPC->getType() == llvm::Type::getFloatTy(CPV->getContext())
1553 : FPC->getType() == llvm::Type::getDoubleTy(CPV->getContext()) ?
"double" :
"long double")
1554 <<
"*)&FPConstant" << I->second <<
')';
1557 if (FPC->getType() == llvm::Type::getFloatTy(CPV->getContext()))
1558 V = FPC->getValueAPF().convertToFloat();
1559 else if (FPC->getType() == llvm::Type::getDoubleTy(CPV->getContext()))
1560 V = FPC->getValueAPF().convertToDouble();
1565 llvm::APFloat Tmp = FPC->getValueAPF();
1567 Tmp.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmTowardZero, &LosesInfo);
1568 V = Tmp.convertToDouble();
1571 if (std::isnan(V)) {
1577 const unsigned long QuietNaN = 0x7ff8UL;
1583 uint64_t ll = llvm::DoubleToBits(V);
1584 snprintf(Buffer,
sizeof(Buffer),
"0x%" PRIx64, ll);
1586 std::string Num(&Buffer[0], &Buffer[6]);
1587 unsigned long Val = strtoul(Num.c_str(), 0, 16);
1589 if (FPC->getType() == llvm::Type::getFloatTy(FPC->getContext()))
1590 Out <<
"LLVM_NAN" << (Val == QuietNaN ?
"" :
"S") <<
"F(\"" << Buffer <<
"\") /*nan*/ ";
1592 Out <<
"LLVM_NAN" << (Val == QuietNaN ?
"" :
"S") <<
"(\"" << Buffer <<
"\") /*nan*/ ";
1593 }
else if (std::isinf(V)) {
1597 Out <<
"LLVM_INF" << (FPC->getType() == llvm::Type::getFloatTy(FPC->getContext()) ?
"F" :
"")
1601 #if HAVE_PRINTF_A && ENABLE_CBE_PRINTF_A 1604 snprintf(Buffer,
sizeof(Buffer),
"%a", V);
1607 Num =
ftostr(FPC->getValueAPF());
1615 case llvm::Type::ArrayTyID: {
1616 llvm::ArrayType *AT = llvm::cast<llvm::ArrayType>(CPV->getType());
1622 printType(Out, CPV->getType());
1625 if (llvm::ConstantArray *CA = llvm::dyn_cast<llvm::ConstantArray>(CPV)) {
1626 printConstantArray(CA, Static);
1627 }
else if (llvm::ConstantDataSequential *CDS = llvm::dyn_cast<llvm::ConstantDataSequential>(CPV)) {
1628 printConstantDataSequential(CDS, Static);
1630 Assert(llvm::isa<llvm::ConstantAggregateZero>(CPV) || llvm::isa<llvm::UndefValue>(CPV));
1631 if (AT->getNumElements()) {
1633 llvm::Constant *CZ = llvm::Constant::getNullValue(AT->getElementType());
1634 printConstant(CZ, Static);
1635 for (
unsigned i = 1, e = (
unsigned)AT->getNumElements(); i != e; ++i) {
1637 printConstant(CZ, Static);
1647 case llvm::Type::VectorTyID: {
1648 llvm::VectorType *VT = llvm::dyn_cast<llvm::VectorType>(CPV->getType());
1650 if (llvm::isa<llvm::ConstantAggregateZero>(CPV)) {
1652 const char *setZeroFunc =
lGetTypedFunc(
"setzero", VT->getElementType(), vectorWidth);
1653 Assert(setZeroFunc != NULL);
1654 Out << setZeroFunc <<
"()";
1655 }
else if (llvm::isa<llvm::UndefValue>(CPV)) {
1658 const char *undefFunc =
lGetTypedFunc(
"undef", VT->getElementType(), vectorWidth);
1659 Assert(undefFunc != NULL);
1660 Out << undefFunc <<
"()";
1662 const char *smearFunc =
lGetTypedFunc(
"smear", VT->getElementType(), vectorWidth);
1664 if (llvm::ConstantVector *CV = llvm::dyn_cast<llvm::ConstantVector>(CPV)) {
1665 llvm::Constant *splatValue = CV->getSplatValue();
1666 if (splatValue != NULL && smearFunc != NULL) {
1669 Out << smearFunc <<
"(";
1670 printConstant(splatValue, Static);
1674 printType(Out, CPV->getType());
1676 printConstantVector(CV, Static);
1679 }
else if (llvm::ConstantDataVector *CDV = llvm::dyn_cast<llvm::ConstantDataVector>(CPV)) {
1680 llvm::Constant *splatValue = CDV->getSplatValue();
1681 if (splatValue != NULL && smearFunc != NULL) {
1682 Out << smearFunc <<
"(";
1683 printConstant(splatValue, Static);
1685 }
else if (VectorConstantMap.find(CDV) != VectorConstantMap.end()) {
1688 unsigned index = VectorConstantMap[CDV];
1689 int alignment = 4 * std::min(vectorWidth, 16);
1691 Out <<
"__load<" << alignment <<
">(";
1696 printSimpleType(Out, CDV->getType(),
true,
"");
1699 Out <<
"(VectorConstant" << index <<
"))";
1701 printType(Out, CPV->getType());
1703 printConstantDataSequential(CDV, Static);
1707 llvm::report_fatal_error(
"Unexpected vector type");
1713 case llvm::Type::StructTyID:
1716 printType(Out, CPV->getType());
1719 if (llvm::isa<llvm::ConstantAggregateZero>(CPV) || llvm::isa<llvm::UndefValue>(CPV)) {
1720 llvm::StructType *ST = llvm::cast<llvm::StructType>(CPV->getType());
1722 if (ST->getNumElements()) {
1724 printConstant(llvm::Constant::getNullValue(ST->getElementType(0)), Static);
1725 for (
unsigned i = 1, e = ST->getNumElements(); i != e; ++i) {
1727 printConstant(llvm::Constant::getNullValue(ST->getElementType(i)), Static);
1733 if (CPV->getNumOperands()) {
1735 printConstant(llvm::cast<llvm::Constant>(CPV->getOperand(0)), Static);
1736 for (
unsigned i = 1, e = CPV->getNumOperands(); i != e; ++i) {
1738 printConstant(llvm::cast<llvm::Constant>(CPV->getOperand(i)), Static);
1745 case llvm::Type::PointerTyID:
1746 if (llvm::isa<llvm::ConstantPointerNull>(CPV)) {
1748 printType(Out, CPV->getType());
1749 Out <<
")/*NULL*/0)";
1751 }
else if (llvm::GlobalValue *GV = llvm::dyn_cast<llvm::GlobalValue>(CPV)) {
1752 writeOperand(GV, Static);
1758 llvm::errs() <<
"Unknown constant type: " << *CPV <<
"\n";
1760 llvm_unreachable(0);
1767 bool CWriter::printConstExprCast(
const llvm::ConstantExpr *CE,
bool Static) {
1768 bool NeedsExplicitCast =
false;
1769 llvm::Type *Ty = CE->getOperand(0)->getType();
1770 bool TypeIsSigned =
false;
1771 switch (CE->getOpcode()) {
1772 case llvm::Instruction::Add:
1773 case llvm::Instruction::Sub:
1774 case llvm::Instruction::Mul:
1777 case llvm::Instruction::LShr:
1778 case llvm::Instruction::URem:
1779 case llvm::Instruction::UDiv:
1780 NeedsExplicitCast =
true;
1782 case llvm::Instruction::AShr:
1783 case llvm::Instruction::SRem:
1784 case llvm::Instruction::SDiv:
1785 NeedsExplicitCast =
true;
1786 TypeIsSigned =
true;
1788 case llvm::Instruction::SExt:
1790 NeedsExplicitCast =
true;
1791 TypeIsSigned =
true;
1793 case llvm::Instruction::ZExt:
1794 case llvm::Instruction::Trunc:
1795 case llvm::Instruction::FPTrunc:
1796 case llvm::Instruction::FPExt:
1797 case llvm::Instruction::UIToFP:
1798 case llvm::Instruction::SIToFP:
1799 case llvm::Instruction::FPToUI:
1800 case llvm::Instruction::FPToSI:
1801 case llvm::Instruction::PtrToInt:
1802 case llvm::Instruction::IntToPtr:
1803 case llvm::Instruction::BitCast:
1805 NeedsExplicitCast =
true;
1810 if (NeedsExplicitCast) {
1812 if (Ty->isIntegerTy() && Ty != llvm::Type::getInt1Ty(Ty->getContext()))
1813 printSimpleType(Out, Ty, TypeIsSigned);
1818 return NeedsExplicitCast;
1824 void CWriter::printConstantWithCast(llvm::Constant *CPV,
unsigned Opcode) {
1827 llvm::Type *OpTy = CPV->getType();
1830 bool shouldCast =
false;
1831 bool typeIsSigned =
false;
1841 case llvm::Instruction::Add:
1842 case llvm::Instruction::Sub:
1843 case llvm::Instruction::Mul:
1846 case llvm::Instruction::LShr:
1847 case llvm::Instruction::UDiv:
1848 case llvm::Instruction::URem:
1851 case llvm::Instruction::AShr:
1852 case llvm::Instruction::SDiv:
1853 case llvm::Instruction::SRem:
1855 typeIsSigned =
true;
1863 printSimpleType(Out, OpTy, typeIsSigned);
1865 printConstant(CPV,
false);
1868 printConstant(CPV,
false);
1871 std::string CWriter::GetValueName(
const llvm::Value *Operand) {
1874 if (
const llvm::GlobalAlias *GA = llvm::dyn_cast<llvm::GlobalAlias>(Operand)) {
1875 if (
const llvm::Value *V = GA->getAliasee())
1880 if (
const llvm::GlobalValue *GV = llvm::dyn_cast<llvm::GlobalValue>(Operand)) {
1885 return CBEMangle(Operand->getName().str().c_str());
1888 std::string Name = std::string(Operand->getName());
1891 unsigned &No = AnonValueNumbers[Operand];
1893 No = ++NextAnonValueNumber;
1894 Name =
"tmp__" + llvm::utostr(No);
1897 std::string VarName;
1898 VarName.reserve(Name.capacity());
1900 for (std::string::iterator I = Name.begin(), E = Name.end(); I != E; ++I) {
1903 if (!((ch >=
'a' && ch <=
'z') || (ch >=
'A' && ch <=
'Z') || (ch >=
'0' && ch <=
'9') || ch ==
'_')) {
1905 snprintf(buffer,
sizeof(buffer),
"_%x_", ch);
1911 if (llvm::isa<llvm::BasicBlock>(Operand))
1912 VarName +=
"_label";
1921 void CWriter::writeInstComputationInline(llvm::Instruction &I) {
1925 bool NeedBoolTrunc =
false;
1926 if (I.getType() == llvm::Type::getInt1Ty(I.getContext()) && !llvm::isa<llvm::ICmpInst>(I) &&
1927 !llvm::isa<llvm::FCmpInst>(I))
1928 NeedBoolTrunc =
true;
1939 void CWriter::writeOperandInternal(llvm::Value *Operand,
bool Static) {
1940 if (llvm::Instruction *I = llvm::dyn_cast<llvm::Instruction>(Operand))
1942 if (isInlinableInst(*I) && !isDirectAlloca(I)) {
1944 writeInstComputationInline(*I);
1949 llvm::Constant *CPV = llvm::dyn_cast<llvm::Constant>(Operand);
1951 if (CPV && !llvm::isa<llvm::GlobalValue>(CPV))
1952 printConstant(CPV, Static);
1954 Out << GetValueName(Operand);
1957 void CWriter::writeOperand(llvm::Value *Operand,
bool Static) {
1958 bool isAddressImplicit = isAddressExposed(Operand);
1959 if (isAddressImplicit)
1962 writeOperandInternal(Operand, Static);
1964 if (isAddressImplicit)
1972 bool CWriter::writeInstructionCast(
const llvm::Instruction &I) {
1973 llvm::Type *Ty = I.getOperand(0)->getType();
1974 switch (I.getOpcode()) {
1975 case llvm::Instruction::Add:
1976 case llvm::Instruction::Sub:
1977 case llvm::Instruction::Mul:
1980 case llvm::Instruction::LShr:
1981 case llvm::Instruction::URem:
1982 case llvm::Instruction::UDiv:
1984 printSimpleType(Out, Ty,
false);
1987 case llvm::Instruction::AShr:
1988 case llvm::Instruction::SRem:
1989 case llvm::Instruction::SDiv:
1991 printSimpleType(Out, Ty,
true);
2003 void CWriter::writeOperandWithCast(llvm::Value *Operand,
unsigned Opcode) {
2006 llvm::Type *OpTy = Operand->getType();
2009 bool shouldCast =
false;
2012 bool castIsSigned =
false;
2021 case llvm::Instruction::Add:
2022 case llvm::Instruction::Sub:
2023 case llvm::Instruction::Mul:
2026 case llvm::Instruction::LShr:
2027 case llvm::Instruction::UDiv:
2028 case llvm::Instruction::URem:
2030 castIsSigned =
false;
2032 case llvm::Instruction::GetElementPtr:
2033 case llvm::Instruction::AShr:
2034 case llvm::Instruction::SDiv:
2035 case llvm::Instruction::SRem:
2037 castIsSigned =
true;
2045 printSimpleType(Out, OpTy, castIsSigned);
2047 writeOperand(Operand);
2050 writeOperand(Operand);
2055 void CWriter::writeOperandWithCast(llvm::Value *Operand,
const llvm::ICmpInst &Cmp) {
2061 bool shouldCast = Cmp.isRelational();
2066 writeOperand(Operand);
2071 bool castIsSigned = Cmp.isSigned();
2074 llvm::Type *OpTy = Operand->getType();
2075 if (OpTy->isPointerTy())
2076 OpTy = TD->getIntPtrType(Operand->getContext());
2079 printSimpleType(Out, OpTy, castIsSigned);
2081 writeOperand(Operand);
2091 Out <<
"#ifndef __GNUC__ /* Can only support \"linkonce\" vars with GCC */\n" 2092 <<
"#define __attribute__(X)\n" 2096 Out <<
"#if defined(__GNUC__) && defined(__APPLE_CC__)\n" 2097 <<
"#define __EXTERNAL_WEAK__ __attribute__((weak_import))\n" 2098 <<
"#elif defined(__GNUC__)\n" 2099 <<
"#define __EXTERNAL_WEAK__ __attribute__((weak))\n" 2101 <<
"#define __EXTERNAL_WEAK__\n" 2105 Out <<
"#if defined(__GNUC__) && defined(__APPLE_CC__)\n" 2106 <<
"#define __ATTRIBUTE_WEAK__\n" 2107 <<
"#elif defined(__GNUC__)\n" 2108 <<
"#define __ATTRIBUTE_WEAK__ __attribute__((weak))\n" 2110 <<
"#define __ATTRIBUTE_WEAK__\n" 2114 Out <<
"#if defined(__GNUC__)\n" 2115 <<
"#define __HIDDEN__ __attribute__((visibility(\"hidden\")))\n" 2149 Out <<
"#if (defined(__GNUC__) || defined(__clang__)) && !defined(__INTEL_COMPILER)\n" 2150 <<
"#define LLVM_NAN(NanStr) __builtin_nan(NanStr) /* Double */\n" 2151 <<
"#define LLVM_NANF(NanStr) __builtin_nanf(NanStr) /* Float */\n" 2152 <<
"#define LLVM_NANS(NanStr) __builtin_nans(NanStr) /* Double */\n" 2153 <<
"#define LLVM_NANSF(NanStr) __builtin_nansf(NanStr) /* Float */\n" 2154 <<
"#define LLVM_INF __builtin_inf() /* Double */\n" 2155 <<
"#define LLVM_INFF __builtin_inff() /* Float */\n" 2156 <<
"//#define LLVM_PREFETCH(addr,rw,locality) " 2157 "__builtin_prefetch(addr,rw,locality)\n" 2158 <<
"//#define __ATTRIBUTE_CTOR__ __attribute__((constructor))\n" 2159 <<
"//#define __ATTRIBUTE_DTOR__ __attribute__((destructor))\n" 2160 <<
"#elif defined(_MSC_VER) || defined(__INTEL_COMPILER)\n" 2161 <<
"#include <limits>\n" 2162 <<
"#define LLVM_NAN(NanStr) std::numeric_limits<double>::quiet_NaN()\n" 2163 <<
"#define LLVM_NANF(NanStr) std::numeric_limits<float>::quiet_NaN()\n" 2164 <<
"#define LLVM_NANS(NanStr) std::numeric_limits<double>::signaling_NaN()\n" 2165 <<
"#define LLVM_NANSF(NanStr) std::numeric_limits<float>::signaling_NaN()\n" 2166 <<
"#define LLVM_INF std::numeric_limits<double>::infinity()\n" 2167 <<
"#define LLVM_INFF std::numeric_limits<float>::infinity()\n" 2168 <<
"//#define LLVM_PREFETCH(addr,rw,locality) /* PREFETCH */\n" 2169 <<
"//#define __ATTRIBUTE_CTOR__\n" 2170 <<
"//#define __ATTRIBUTE_DTOR__\n" 2172 <<
"#error \"Not MSVC, clang, or g++?\"\n" 2180 Out <<
"#if (defined(__GNUC__) || defined(__clang__))\n" 2181 <<
"#define LLVM_ASM(X) __asm(X)\n" 2184 Out <<
"#if defined(__clang__) || defined(__INTEL_COMPILER) || " 2185 "(__GNUC__ < 4) /* Old GCCs, or compilers not GCC */ \n" 2186 <<
"#define __builtin_stack_save() 0 /* not implemented */\n" 2187 <<
"#define __builtin_stack_restore(X) /* noop */\n" 2194 Out <<
"#if __GNUC__ && __LP64__ /* 128-bit integer types */\n" 2195 <<
"typedef int __attribute__((mode(TI))) llvmInt128;\n" 2196 <<
"typedef unsigned __attribute__((mode(TI))) llvmUInt128;\n" 2201 Out <<
"#define CODE_FOR_MAIN() /* Any target-specific code for main()*/\n";
2206 static void FindStaticTors(llvm::GlobalVariable *GV, std::set<llvm::Function *> &StaticTors) {
2207 llvm::ConstantArray *InitList = llvm::dyn_cast<llvm::ConstantArray>(GV->getInitializer());
2211 for (
unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i)
2212 if (llvm::ConstantStruct *CS = llvm::dyn_cast<llvm::ConstantStruct>(InitList->getOperand(i))) {
2213 if (CS->getNumOperands() != 2)
2216 if (CS->getOperand(1)->isNullValue())
2218 llvm::Constant *FP = CS->getOperand(1);
2219 if (llvm::ConstantExpr *CE = llvm::dyn_cast<llvm::ConstantExpr>(FP))
2221 FP = CE->getOperand(0);
2222 if (llvm::Function *F = llvm::dyn_cast<llvm::Function>(FP))
2223 StaticTors.insert(F);
2233 if (GV->hasAppendingLinkage() && GV->use_empty()) {
2234 if (GV->getName() ==
"llvm.global_ctors")
2236 else if (GV->getName() ==
"llvm.global_dtors")
2243 if (GV->getSection() ==
"llvm.metadata")
2252 for (
unsigned i = 0; i != Length; ++i) {
2253 unsigned char C = Str[i];
2254 if (isprint(C) && C !=
'\\' && C !=
'"')
2263 Out <<
"\\x" << llvm::hexdigit(C >> 4) << llvm::hexdigit(C & 0x0F);
2273 bool CWriter::doInitialization(llvm::Module &M) {
2274 llvm::FunctionPass::doInitialization(M);
2279 TD =
new llvm::DataLayout(&M);
2280 IL =
new llvm::IntrinsicLowering(*TD);
2284 #if ISPC_LLVM_VERSION <= ISPC_LLVM_8_0 2285 IL->AddPrototypes(M);
2289 std::string
Triple = TheModule->getTargetTriple();
2291 Triple = llvm::sys::getDefaultTargetTriple();
2294 if (
const llvm::Target *Match = llvm::TargetRegistry::lookupTarget(Triple, E))
2295 TAsm = Match->createMCAsmInfo(Triple);
2297 TAsm =
new CBEMCAsmInfo();
2298 MRI =
new llvm::MCRegisterInfo();
2299 TCtx =
new llvm::MCContext(TAsm, MRI, NULL);
2304 std::set<llvm::Function *> StaticCtors, StaticDtors;
2305 for (llvm::Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) {
2318 Out <<
"/*******************************************************************\n";
2319 Out <<
" This file has been automatically generated by ispc\n";
2320 Out <<
" DO NOT EDIT THIS FILE DIRECTLY\n";
2321 Out <<
" *******************************************************************/\n\n";
2323 Out <<
"/* Provide Declarations */\n";
2324 Out <<
"#include <stdarg.h>\n";
2325 Out <<
"#include <setjmp.h>\n";
2326 Out <<
"#include <limits.h>\n";
2327 Out <<
"#include <stdlib.h>\n";
2328 Out <<
"#ifdef _MSC_VER\n";
2329 Out <<
" #define NOMINMAX\n";
2330 Out <<
" #include <windows.h>\n";
2331 Out <<
"#endif // _MSC_VER\n";
2332 Out <<
"#include <stdlib.h>\n";
2333 Out <<
"#include <stdint.h>\n";
2334 Out <<
"/* get a declaration for alloca */\n";
2335 Out <<
"#ifdef _MSC_VER\n";
2336 Out <<
" #include <malloc.h>\n";
2337 Out <<
" #define alloca _alloca\n";
2339 Out <<
" #include <alloca.h>\n";
2340 Out <<
"#endif\n\n";
2343 Out <<
"#define ISPC_FAST_MATH 1\n";
2345 Out <<
"#undef ISPC_FAST_MATH\n";
2349 Out <<
"#define ISPC_FORCE_ALIGNED_MEMORY\n";
2352 Out <<
"#include \"" << includeName <<
"\"\n";
2354 Out <<
"\n/* Basic Library Function Declarations */\n";
2355 Out <<
"extern \"C\" {\n";
2356 Out <<
"int puts(unsigned char *);\n";
2357 Out <<
"unsigned int putchar(unsigned int);\n";
2358 Out <<
"int fflush(void *);\n";
2359 Out <<
"int printf(const unsigned char *, ...);\n";
2360 Out <<
"uint8_t *memcpy(uint8_t *, uint8_t *, uint64_t );\n";
2361 Out <<
"uint8_t *memset(uint8_t *, uint8_t, uint64_t );\n";
2362 Out <<
"void memset_pattern16(void *, const void *, uint64_t );\n";
2369 <<
"#ifndef __cplusplus\ntypedef unsigned char bool;\n#endif\n" 2371 <<
"\n\n/* Support for floating point constants */\n" 2372 <<
"typedef uint64_t ConstantDoubleTy;\n" 2373 <<
"typedef uint32_t ConstantFloatTy;\n" 2374 <<
"typedef struct { unsigned long long f1; unsigned short f2; " 2375 "unsigned short pad[3]; } ConstantFP80Ty;\n" 2377 <<
"typedef struct { uint64_t f1, f2; } ConstantFP128Ty;\n" 2378 <<
"\n\n/* Global Declarations */\n\n";
2383 if (!M.getModuleInlineAsm().empty()) {
2384 Out <<
"/* Module asm statements */\n" 2388 std::string Asm = M.getModuleInlineAsm();
2390 size_t NewLine = Asm.find_first_of(
'\n', CurPos);
2391 while (NewLine != std::string::npos) {
2397 CurPos = NewLine + 1;
2398 NewLine = Asm.find_first_of(
'\n', CurPos);
2403 <<
"/* End Module asm statements */\n";
2410 if (!M.global_empty()) {
2411 Out <<
"\n/* External Global Variable Declarations */\n";
2412 for (llvm::Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) {
2414 if (I->hasExternalLinkage() || I->hasExternalWeakLinkage() || I->hasCommonLinkage())
2416 else if (I->hasDLLImportStorageClass())
2417 Out <<
"__declspec(dllimport) ";
2422 if (I->isThreadLocal())
2425 printType(Out, I->getType()->getElementType(),
false, GetValueName(&*I));
2427 if (I->hasExternalWeakLinkage())
2428 Out <<
" __EXTERNAL_WEAK__";
2434 if (!M.global_empty()) {
2435 Out <<
"\n\n/* Global Variable Declarations */\n";
2436 for (llvm::Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
2437 if (!I->isDeclaration()) {
2442 if (I->hasLocalLinkage())
2448 if (I->isThreadLocal())
2451 printType(Out, I->getType()->getElementType(),
false, GetValueName(&*I));
2453 if (I->hasLinkOnceLinkage())
2454 Out <<
" __attribute__((common))";
2455 else if (I->hasCommonLinkage())
2456 Out <<
" __ATTRIBUTE_WEAK__";
2457 else if (I->hasWeakLinkage())
2458 Out <<
" __ATTRIBUTE_WEAK__";
2459 else if (I->hasExternalWeakLinkage())
2460 Out <<
" __EXTERNAL_WEAK__";
2461 if (I->hasHiddenVisibility())
2462 Out <<
" __HIDDEN__";
2468 Out <<
"\n/* Function Declarations */\n";
2469 Out <<
"extern \"C\" {\n";
2472 llvm::SmallVector<const llvm::Function *, 8> intrinsicsToDefine;
2474 for (llvm::Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
2477 if (I->isIntrinsic()) {
2478 switch (I->getIntrinsicID()) {
2481 case llvm::Intrinsic::uadd_with_overflow:
2482 case llvm::Intrinsic::sadd_with_overflow:
2483 case llvm::Intrinsic::umul_with_overflow:
2484 intrinsicsToDefine.push_back(&*I);
2490 if (I->getName() ==
"setjmp" || I->getName() ==
"abort" || I->getName() ==
"longjmp" ||
2491 I->getName() ==
"_setjmp" || I->getName() ==
"memset" || I->getName() ==
"memset_pattern16" ||
2492 I->getName() ==
"puts" || I->getName() ==
"printf" || I->getName() ==
"putchar" ||
2493 I->getName() ==
"fflush" ||
2495 I->getName() ==
"malloc" || I->getName() ==
"posix_memalign" || I->getName() ==
"free" ||
2496 I->getName() ==
"_aligned_malloc" || I->getName() ==
"_aligned_free")
2500 std::string name = std::string(I->getName());
2501 if (name.size() > 2 && name[0] ==
'_' && name[1] ==
'_')
2504 if (I->hasExternalWeakLinkage())
2506 printFunctionSignature(&*I,
true);
2507 if (I->hasWeakLinkage() || I->hasLinkOnceLinkage())
2508 Out <<
" __ATTRIBUTE_WEAK__";
2509 if (I->hasExternalWeakLinkage())
2510 Out <<
" __EXTERNAL_WEAK__";
2511 if (StaticCtors.count(&*I))
2512 Out <<
" __ATTRIBUTE_CTOR__";
2513 if (StaticDtors.count(&*I))
2514 Out <<
" __ATTRIBUTE_DTOR__";
2515 if (I->hasHiddenVisibility())
2516 Out <<
" __HIDDEN__";
2519 if (I->hasName() && I->getName()[0] == 1)
2520 Out <<
" LLVM_ASM(\"" << I->getName().substr(1) <<
"\")";
2527 Out <<
"\n\n/* Function Bodies */\n";
2531 Out <<
"template <typename A, typename B> static inline int llvm_fcmp_ord(A X, B Y) { ";
2532 Out <<
"return X == X && Y == Y; }\n";
2533 Out <<
"template <typename A, typename B> static inline int llvm_fcmp_uno(A X, B Y) { ";
2534 Out <<
"return X != X || Y != Y; }\n";
2535 Out <<
"template <typename A, typename B> static inline int llvm_fcmp_ueq(A X, B Y) { ";
2536 Out <<
"return X == Y || llvm_fcmp_uno(X, Y); }\n";
2537 Out <<
"template <typename A, typename B> static inline int llvm_fcmp_une(A X, B Y) { ";
2538 Out <<
"return X != Y; }\n";
2539 Out <<
"template <typename A, typename B> static inline int llvm_fcmp_ult(A X, B Y) { ";
2540 Out <<
"return X < Y || llvm_fcmp_uno(X, Y); }\n";
2541 Out <<
"template <typename A, typename B> static inline int llvm_fcmp_ugt(A X, B Y) { ";
2542 Out <<
"return X > Y || llvm_fcmp_uno(X, Y); }\n";
2543 Out <<
"template <typename A, typename B> static inline int llvm_fcmp_ule(A X, B Y) { ";
2544 Out <<
"return X <= Y || llvm_fcmp_uno(X, Y); }\n";
2545 Out <<
"template <typename A, typename B> static inline int llvm_fcmp_uge(A X, B Y) { ";
2546 Out <<
"return X >= Y || llvm_fcmp_uno(X, Y); }\n";
2547 Out <<
"template <typename A, typename B> static inline int llvm_fcmp_oeq(A X, B Y) { ";
2548 Out <<
"return X == Y ; }\n";
2549 Out <<
"template <typename A, typename B> static inline int llvm_fcmp_one(A X, B Y) { ";
2550 Out <<
"return X != Y && llvm_fcmp_ord(X, Y); }\n";
2551 Out <<
"template <typename A, typename B> static inline int llvm_fcmp_olt(A X, B Y) { ";
2552 Out <<
"return X < Y ; }\n";
2553 Out <<
"template <typename A, typename B> static inline int llvm_fcmp_ogt(A X, B Y) { ";
2554 Out <<
"return X > Y ; }\n";
2555 Out <<
"template <typename A, typename B> static inline int llvm_fcmp_ole(A X, B Y) { ";
2556 Out <<
"return X <= Y ; }\n";
2557 Out <<
"template <typename A, typename B> static inline int llvm_fcmp_oge(A X, B Y) { ";
2558 Out <<
"return X >= Y ; }\n";
2559 Out <<
"template <typename A> A *Memset(A *ptr, int count, size_t len) { ";
2560 Out <<
"return (A *)memset(ptr, count, len); }\n";
2563 for (llvm::SmallVector<const llvm::Function *, 8>::const_iterator I = intrinsicsToDefine.begin(),
2564 E = intrinsicsToDefine.end();
2566 printIntrinsicDefinition(**I, Out);
2570 if (!M.global_empty()) {
2571 Out <<
"\n\n/* Global Variable Definitions and Initialization */\n";
2572 for (llvm::Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
2573 if (!I->isDeclaration()) {
2578 if (I->hasLocalLinkage())
2580 else if (I->hasDLLImportStorageClass())
2581 Out <<
"__declspec(dllimport) ";
2582 else if (I->hasDLLExportStorageClass())
2583 Out <<
"__declspec(dllexport) ";
2585 if (I->isThreadLocal())
2588 printType(Out, I->getType()->getElementType(),
false, GetValueName(&*I));
2590 if (I->hasLinkOnceLinkage())
2591 Out <<
" __attribute__((common))";
2592 else if (I->hasWeakLinkage())
2593 Out <<
" __ATTRIBUTE_WEAK__";
2594 else if (I->hasCommonLinkage())
2595 Out <<
" __ATTRIBUTE_WEAK__";
2597 if (I->hasHiddenVisibility())
2598 Out <<
" __HIDDEN__";
2606 if (!I->getInitializer()->isNullValue()) {
2611 Out <<
"/* vec16_i64 should be loaded carefully on knc */\n";
2612 Out <<
"\n#if defined(KNC) \n";
2614 Out <<
"\n#endif \n";
2618 writeOperand(I->getInitializer(),
false);
2620 }
else if (I->hasWeakLinkage()) {
2625 if (I->getInitializer()->getType()->isStructTy() || I->getInitializer()->getType()->isVectorTy()) {
2627 }
else if (I->getInitializer()->getType()->isArrayTy()) {
2633 writeOperand(I->getInitializer(),
false);
2644 void CWriter::printFloatingPointConstants(llvm::Function &F) {
2653 printFloatingPointConstants(*I);
2658 void CWriter::printFloatingPointConstants(
const llvm::Constant *C) {
2660 if (
const llvm::ConstantExpr *CE = llvm::dyn_cast<llvm::ConstantExpr>(C)) {
2661 for (
unsigned i = 0, e = CE->getNumOperands(); i != e; ++i)
2662 printFloatingPointConstants(CE->getOperand(i));
2667 const llvm::ConstantFP *FPC = llvm::dyn_cast<llvm::ConstantFP>(C);
2672 FPConstantMap.count(FPC))
2675 FPConstantMap[FPC] = FPCounter;
2677 if (FPC->getType() == llvm::Type::getDoubleTy(FPC->getContext())) {
2678 double Val = FPC->getValueAPF().convertToDouble();
2679 uint64_t i = FPC->getValueAPF().bitcastToAPInt().getZExtValue();
2680 Out <<
"static const ConstantDoubleTy FPConstant" << FPCounter++ <<
" = 0x" << llvm::utohexstr(i)
2681 <<
"ULL; /* " << Val <<
" */\n";
2682 }
else if (FPC->getType() == llvm::Type::getFloatTy(FPC->getContext())) {
2683 float Val = FPC->getValueAPF().convertToFloat();
2684 uint32_t i = (uint32_t)FPC->getValueAPF().bitcastToAPInt().getZExtValue();
2685 Out <<
"static const ConstantFloatTy FPConstant" << FPCounter++ <<
" = 0x" << llvm::utohexstr(i) <<
"U; /* " 2687 }
else if (FPC->getType() == llvm::Type::getX86_FP80Ty(FPC->getContext())) {
2689 llvm::APInt api = FPC->getValueAPF().bitcastToAPInt();
2690 const uint64_t *p = api.getRawData();
2691 Out <<
"static const ConstantFP80Ty FPConstant" << FPCounter++ <<
" = { 0x" << llvm::utohexstr(p[0])
2692 <<
"ULL, 0x" << llvm::utohexstr((uint16_t)p[1]) <<
",{0,0,0}" 2693 <<
"}; /* Long double constant */\n";
2694 }
else if (FPC->getType() == llvm::Type::getPPC_FP128Ty(FPC->getContext()) ||
2695 FPC->getType() == llvm::Type::getFP128Ty(FPC->getContext())) {
2696 llvm::APInt api = FPC->getValueAPF().bitcastToAPInt();
2697 const uint64_t *p = api.getRawData();
2698 Out <<
"static const ConstantFP128Ty FPConstant" << FPCounter++ <<
" = { 0x" << llvm::utohexstr(p[0]) <<
", 0x" 2699 << llvm::utohexstr(p[1]) <<
"}; /* Long double constant */\n";
2702 llvm_unreachable(
"Unknown float type!");
2710 void CWriter::printVectorConstants(llvm::Function &F) {
2714 const llvm::ConstantDataVector *CDV = llvm::dyn_cast<llvm::ConstantDataVector>(*I);
2720 if (CDV->getSplatValue() != NULL)
2724 int alignment = 4 * std::min(vectorWidth, 16);
2726 Out <<
"static const ";
2727 printSimpleType(Out, CDV->getElementType(),
true,
"");
2728 Out <<
"__attribute__ ((aligned(" << alignment <<
"))) ";
2729 Out <<
"VectorConstant" << VectorConstantIndex <<
"[] = { ";
2730 for (
int i = 0; i < (int)CDV->getNumElements(); ++i) {
2731 printConstant(CDV->getElementAsConstant(i),
false);
2736 VectorConstantMap[CDV] = VectorConstantIndex++;
2744 void CWriter::printModuleTypes() {
2745 Out <<
"\n/* Helper union for bitcasts */\n";
2746 Out <<
"typedef union {\n";
2747 Out <<
" unsigned int Int32;\n";
2748 Out <<
" unsigned long long Int64;\n";
2749 Out <<
" float Float;\n";
2750 Out <<
" double Double;\n";
2751 Out <<
"} llvmBitCastUnion;\n";
2752 Out <<
"\n/* This is special class, designed for operations with long int.*/ \n";
2753 Out <<
"namespace { \n";
2754 Out <<
"template <int num_bits> \n";
2755 Out <<
"struct iN { \n";
2756 Out <<
" int num[num_bits / (sizeof (int) * 8)]; \n";
2758 Out <<
" iN () {} \n";
2760 Out <<
" iN (const char *val) { \n";
2761 Out <<
" if (val == NULL) \n";
2762 Out <<
" return; \n";
2763 Out <<
" int length = num_bits / (sizeof (int) * 8); \n";
2764 Out <<
" int val_len = 0; \n";
2765 Out <<
" for (val_len = 0; val[val_len]; (val_len)++); \n";
2766 Out <<
" for (int i = 0; (i < val_len && i < num_bits); i++) \n";
2767 Out <<
" num[i / (sizeof (int) * 8)] = (num[i / (sizeof (int) * 8)] << 1) | (val[i] - '0'); \n";
2770 Out <<
" ~iN () {} \n";
2772 Out <<
" iN operator >> (const iN rhs) { \n";
2773 Out <<
" iN res; \n";
2774 Out <<
" int length = num_bits / (sizeof (int) * 8); \n";
2775 Out <<
" int cells_shift = rhs.num[0] / (sizeof(int) * 8); \n";
2776 Out <<
" int small_shift = rhs.num[0] % (sizeof(int) * 8); \n";
2777 Out <<
" for (int i = 0; i < (length - cells_shift); i++) \n";
2778 Out <<
" res.num[i] = this->num[cells_shift + i]; \n";
2779 Out <<
" for (int i = 0; i < length - 1; i++) { \n";
2780 Out <<
" res.num[i] = this->num[i] >> small_shift; \n";
2781 Out <<
" res.num[i] = ((this->num[i + 1] << ((sizeof(int) * 8) - small_shift))) | res.num[i];\n";
2783 Out <<
" res.num[length - 1] = res.num[length - 1] >> small_shift; \n";
2784 Out <<
" return res; \n";
2787 Out <<
" iN operator & (iN rhs) { \n";
2788 Out <<
" iN res; \n";
2789 Out <<
" int length = num_bits / (sizeof (int) * 8); \n";
2790 Out <<
" for (int i = 0; i < length; i++) \n";
2791 Out <<
" res.num[i] = (this->num[i]) & (rhs.num[i]); \n";
2792 Out <<
" return res; \n";
2795 Out <<
" operator uint32_t() { return this->num[0]; } \n";
2797 Out <<
" template <class T> \n";
2798 Out <<
" friend iN<num_bits> __cast_bits(iN<num_bits> to, T from) { \n";
2799 Out <<
" for (int i = 0; i <" << vectorWidth <<
"; i++) \n";
2800 Out <<
" to.num[i] = ((int*)(&from))[i]; \n";
2801 Out <<
" return to; \n";
2804 Out <<
" template <class T> \n";
2805 Out <<
" friend T __cast_bits(T to, iN<num_bits> from) { \n";
2806 Out <<
" for (int i = 0; i <" << vectorWidth <<
"; i++) \n";
2807 Out <<
" ((int*)(&to))[i] = from.num[i]; \n";
2808 Out <<
" return to; \n";
2811 Out <<
" template <int ALIGN, class T> \n";
2812 Out <<
" friend void __store(T *p, iN<num_bits> val) { \n";
2813 Out <<
" for (int i = 0; i <" << vectorWidth <<
"; i++) \n";
2814 Out <<
" ((int*)p)[i] = val.num[i]; \n";
2821 std::vector<llvm::StructType *> StructTypes;
2822 llvm::TypeFinder typeFinder;
2823 typeFinder.run(*TheModule,
false);
2824 for (llvm::TypeFinder::iterator iter = typeFinder.begin(); iter != typeFinder.end(); ++iter)
2825 StructTypes.push_back(*iter);
2828 std::vector<llvm::ArrayType *> ArrayTypes;
2829 std::vector<llvm::IntegerType *> IntegerTypes;
2830 std::vector<bool> IsVolatile;
2831 std::vector<int> Alignment;
2835 if (StructTypes.empty() && ArrayTypes.empty())
2838 Out <<
"/* Structure and array forward declarations */\n";
2840 unsigned NextTypeID = 0;
2844 for (
unsigned i = 0, e = StructTypes.size(); i != e; ++i) {
2845 llvm::StructType *ST = StructTypes[i];
2847 if (ST->isLiteral() || ST->getName().empty())
2848 UnnamedStructIDs[ST] = NextTypeID++;
2850 std::string Name = getStructName(ST);
2852 Out <<
"struct " << Name <<
";\n";
2855 Out <<
"namespace {\n";
2856 for (
unsigned i = 0, e = ArrayTypes.size(); i != e; ++i) {
2857 llvm::ArrayType *AT = ArrayTypes[i];
2858 ArrayIDs[AT] = NextTypeID++;
2859 std::string Name = getArrayName(AT);
2860 Out <<
" struct " << Name <<
";\n";
2864 for (
unsigned i = 0, e = IntegerTypes.size(); i != e; ++i) {
2865 llvm::IntegerType *IT = IntegerTypes[i];
2866 if (IT->getIntegerBitWidth() <= 64 || Alignment[i] == 0)
2869 Out <<
"typedef struct __attribute__ ((packed, aligned(" << Alignment[i] <<
"))) {\n ";
2870 IsVolatile[i] ? Out <<
" volatile " : Out <<
" ";
2871 printType(Out, IT,
false,
"data");
2873 Out <<
"} iN_" << IT->getIntegerBitWidth() <<
"_align_" << Alignment[i] <<
";\n";
2879 llvm::SmallPtrSet<llvm::Type *, 16> StructArrayPrinted;
2884 Out <<
"/* Structure and array contents */\n";
2885 for (
unsigned i = 0, e = StructTypes.size(); i != e; ++i) {
2886 if (StructTypes[i]->isStructTy())
2888 printContainedStructs(StructTypes[i], StructArrayPrinted);
2891 Out <<
"namespace {\n";
2892 for (
unsigned i = 0, e = ArrayTypes.size(); i != e; ++i)
2893 printContainedArrays(ArrayTypes[i], StructArrayPrinted);
2904 void CWriter::printContainedStructs(llvm::Type *Ty, llvm::SmallPtrSet<llvm::Type *, 16> &Printed) {
2906 if (!(Ty->isStructTy() || Ty->isArrayTy()))
2910 for (llvm::Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); I != E; ++I)
2911 printContainedStructs(*I, Printed);
2913 if (llvm::StructType *ST = llvm::dyn_cast<llvm::StructType>(Ty)) {
2915 if (!Printed.insert(Ty).second)
2919 printType(Out, ST,
false, getStructName(ST),
true);
2922 if (llvm::ArrayType *AT = llvm::dyn_cast<llvm::ArrayType>(Ty)) {
2923 if (!Printed.insert(Ty).second)
2926 Out <<
"namespace {\n";
2927 printType(Out, AT,
false, getArrayName(AT),
true);
2932 void CWriter::printContainedArrays(llvm::ArrayType *ATy, llvm::SmallPtrSet<llvm::Type *, 16> &Printed) {
2933 if (!Printed.insert(ATy).second)
2936 llvm::ArrayType *ChildTy = llvm::dyn_cast<llvm::ArrayType>(ATy->getElementType());
2937 if (ChildTy != NULL)
2938 printContainedArrays(ChildTy, Printed);
2940 printType(Out, ATy,
false, getArrayName(ATy),
true);
2944 void CWriter::printFunctionSignature(
const llvm::Function *F,
bool Prototype) {
2946 bool isStructReturn = F->hasStructRetAttr();
2948 if (F->hasLocalLinkage())
2950 if (F->hasDLLImportStorageClass())
2951 Out <<
"__declspec(dllimport) ";
2952 if (F->hasDLLExportStorageClass())
2953 Out <<
"__declspec(dllexport) ";
2954 switch (F->getCallingConv()) {
2955 case llvm::CallingConv::X86_StdCall:
2956 Out <<
"__attribute__((stdcall)) ";
2958 case llvm::CallingConv::X86_FastCall:
2959 Out <<
"__attribute__((fastcall)) ";
2961 case llvm::CallingConv::X86_ThisCall:
2962 Out <<
"__attribute__((thiscall)) ";
2969 llvm::FunctionType *FT = llvm::cast<llvm::FunctionType>(F->getFunctionType());
2970 const llvm::AttributeList &PAL = F->getAttributes();
2973 llvm::raw_string_ostream FunctionInnards(tstr);
2976 FunctionInnards << GetValueName(F) <<
'(';
2978 bool PrintedArg =
false;
2979 if (!F->isDeclaration()) {
2980 if (!F->arg_empty()) {
2981 llvm::Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
2986 if (isStructReturn) {
2987 Assert(I != E &&
"Invalid struct return function!");
2992 std::string ArgName;
2993 for (; I != E; ++I) {
2995 FunctionInnards <<
", ";
2996 if (I->hasName() || !Prototype)
2997 ArgName = GetValueName(&*I);
3000 llvm::Type *ArgTy = I->getType();
3001 if (PAL.getParamAttributes(Idx).hasAttribute(llvm::Attribute::ByVal)) {
3002 ArgTy = llvm::cast<llvm::PointerType>(ArgTy)->getElementType();
3003 ByValParams.insert(&*I);
3005 printType(FunctionInnards, ArgTy, PAL.getParamAttributes(Idx).hasAttribute(llvm::Attribute::SExt),
3013 llvm::FunctionType::param_iterator I = FT->param_begin(), E = FT->param_end();
3018 if (isStructReturn) {
3019 Assert(I != E &&
"Invalid struct return function!");
3024 for (; I != E; ++I) {
3026 FunctionInnards <<
", ";
3027 llvm::Type *ArgTy = *I;
3028 if (PAL.getParamAttributes(Idx).hasAttribute(llvm::Attribute::ByVal)) {
3029 Assert(ArgTy->isPointerTy());
3030 ArgTy = llvm::cast<llvm::PointerType>(ArgTy)->getElementType();
3032 printType(FunctionInnards, ArgTy, PAL.getParamAttributes(Idx).hasAttribute(llvm::Attribute::SExt));
3038 if (!PrintedArg && FT->isVarArg()) {
3039 FunctionInnards <<
"int vararg_dummy_arg";
3046 if (FT->isVarArg() && PrintedArg) {
3047 FunctionInnards <<
",...";
3048 }
else if (!FT->isVarArg() && !PrintedArg) {
3049 FunctionInnards <<
"void";
3051 FunctionInnards <<
')';
3055 if (!isStructReturn)
3056 RetTy = F->getReturnType();
3059 RetTy = llvm::cast<llvm::PointerType>(FT->getParamType(0))->getElementType();
3063 printType(Out, RetTy, PAL.getParamAttributes(0).hasAttribute(llvm::Attribute::SExt), FunctionInnards.str());
3067 if (!llvm::isa<llvm::BitCastInst>(I))
3069 llvm::Type *SrcTy = I.getOperand(0)->getType();
3070 llvm::Type *DstTy = I.getType();
3071 return (SrcTy->isFloatingPointTy() && DstTy->isIntegerTy()) || (DstTy->isFloatingPointTy() && SrcTy->isIntegerTy());
3074 void CWriter::printFunction(llvm::Function &F) {
3076 bool isStructReturn = F.hasStructRetAttr();
3078 printFunctionSignature(&F,
false);
3082 if (isStructReturn) {
3083 llvm::Type *StructTy = llvm::cast<llvm::PointerType>(F.arg_begin()->getType())->getElementType();
3085 printType(Out, StructTy,
false,
"StructReturn");
3086 Out <<
"; /* Struct return temporary */\n";
3089 printType(Out, F.arg_begin()->getType(),
false, GetValueName(&*(F.arg_begin())));
3090 Out <<
" = &StructReturn;\n";
3093 bool PrintedVar =
false;
3096 for (llvm::inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ++I) {
3097 if (
const llvm::AllocaInst *AI = isDirectAlloca(&*I)) {
3099 printType(Out, AI->getAllocatedType(),
false, GetValueName(AI));
3100 Out <<
"; /* Address-exposed local */\n";
3102 }
else if (I->getType() != llvm::Type::getVoidTy(F.getContext()) && !isInlinableInst(*I)) {
3104 printType(Out, I->getType(),
false, GetValueName(&*I));
3107 if (llvm::isa<llvm::PHINode>(*I)) {
3109 printType(Out, I->getType(),
false, GetValueName(&*I) +
"__PHI");
3118 Out <<
" llvmBitCastUnion " << GetValueName(&*I) <<
"__BITCAST_TEMPORARY;\n";
3126 if (F.hasExternalLinkage() && F.getName() ==
"main")
3127 Out <<
" CODE_FOR_MAIN();\n";
3130 for (llvm::Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
3131 if (llvm::Loop *L = LI->getLoopFor(&*BB)) {
3132 if (L->getHeader()->getIterator() == BB && L->getParentLoop() == 0)
3135 printBasicBlock(&*BB);
3142 void CWriter::printLoop(llvm::Loop *L) {
3143 Out <<
" do { /* Syntactic loop '" << L->getHeader()->getName() <<
"' to make GCC happy */\n";
3144 for (
unsigned i = 0, e = L->getBlocks().size(); i != e; ++i) {
3145 llvm::BasicBlock *BB = L->getBlocks()[i];
3146 llvm::Loop *BBLoop = LI->getLoopFor(BB);
3148 printBasicBlock(BB);
3149 else if (BBLoop != NULL && BB == BBLoop->getHeader() && BBLoop->getParentLoop() == L)
3152 Out <<
" } while (1); /* end of syntactic loop '" << L->getHeader()->getName() <<
"' */\n";
3155 void CWriter::printBasicBlock(llvm::BasicBlock *BB) {
3162 bool NeedsLabel =
false;
3163 for (llvm::pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI)
3164 if (isGotoCodeNecessary(*PI, BB)) {
3170 Out << GetValueName(BB) <<
": {\n";
3173 for (llvm::BasicBlock::iterator II = BB->begin(), E = --BB->end(); II != E; ++II) {
3174 if (!isInlinableInst(*II) && !isDirectAlloca(&*II)) {
3175 if (II->getType() != llvm::Type::getVoidTy(BB->getContext()) && !isInlineAsm(*II))
3179 writeInstComputationInline(*II);
3185 visit(*BB->getTerminator());
3193 void CWriter::visitReturnInst(llvm::ReturnInst &I) {
3195 bool isStructReturn = I.getParent()->getParent()->hasStructRetAttr();
3197 if (isStructReturn) {
3198 Out <<
" return StructReturn;\n";
3203 if (I.getNumOperands() == 0 && &*--I.getParent()->getParent()->end() == I.getParent() &&
3204 (!I.getParent()->size()) == 1) {
3209 if (I.getNumOperands()) {
3211 writeOperand(I.getOperand(0));
3216 void CWriter::visitSwitchInst(llvm::SwitchInst &SI) {
3218 llvm::Value *Cond = SI.getCondition();
3222 Out <<
") {\n default:\n";
3223 printPHICopiesForSuccessor(SI.getParent(), SI.getDefaultDest(), 2);
3224 printBranchToBlock(SI.getParent(), SI.getDefaultDest(), 2);
3227 for (llvm::SwitchInst::CaseIt i = SI.case_begin(), e = SI.case_end(); i != e; ++i) {
3228 llvm::ConstantInt *CaseVal = i->getCaseValue();
3229 llvm::BasicBlock *Succ = i->getCaseSuccessor();
3231 writeOperand(CaseVal);
3233 printPHICopiesForSuccessor(SI.getParent(), Succ, 2);
3234 printBranchToBlock(SI.getParent(), Succ, 2);
3236 if (llvm::Function::iterator(Succ) == std::next(llvm::Function::iterator(SI.getParent())))
3243 void CWriter::visitIndirectBrInst(llvm::IndirectBrInst &IBI) {
3244 Out <<
" goto *(void*)(";
3245 writeOperand(IBI.getOperand(0));
3249 void CWriter::visitUnreachableInst(llvm::UnreachableInst &I) { Out <<
" /*UNREACHABLE*/;\n"; }
3251 bool CWriter::isGotoCodeNecessary(llvm::BasicBlock *From, llvm::BasicBlock *To) {
3255 if (std::next(llvm::Function::iterator(From)) != llvm::Function::iterator(To))
3260 if (LI->getLoopFor(From) != LI->getLoopFor(To))
3265 void CWriter::printPHICopiesForSuccessor(llvm::BasicBlock *CurBlock, llvm::BasicBlock *Successor,
unsigned Indent) {
3266 for (llvm::BasicBlock::iterator I = Successor->begin(); llvm::isa<llvm::PHINode>(I); ++I) {
3267 llvm::PHINode *PN = llvm::cast<llvm::PHINode>(&*I);
3269 llvm::Value *IV = PN->getIncomingValueForBlock(CurBlock);
3270 if (!llvm::isa<llvm::UndefValue>(IV)) {
3271 Out << std::string(Indent,
' ');
3272 Out <<
" " << GetValueName(&*I) <<
"__PHI = ";
3274 Out <<
"; /* for PHI node */\n";
3279 void CWriter::printBranchToBlock(llvm::BasicBlock *CurBB, llvm::BasicBlock *Succ,
unsigned Indent) {
3280 if (isGotoCodeNecessary(CurBB, Succ)) {
3281 Out << std::string(Indent,
' ') <<
" goto ";
3290 void CWriter::visitBranchInst(llvm::BranchInst &I) {
3292 if (I.isConditional()) {
3293 if (isGotoCodeNecessary(I.getParent(), I.getSuccessor(0))) {
3295 writeOperand(I.getCondition());
3298 printPHICopiesForSuccessor(I.getParent(), I.getSuccessor(0), 2);
3299 printBranchToBlock(I.getParent(), I.getSuccessor(0), 2);
3301 if (isGotoCodeNecessary(I.getParent(), I.getSuccessor(1))) {
3302 Out <<
" } else {\n";
3303 printPHICopiesForSuccessor(I.getParent(), I.getSuccessor(1), 2);
3304 printBranchToBlock(I.getParent(), I.getSuccessor(1), 2);
3309 writeOperand(I.getCondition());
3312 printPHICopiesForSuccessor(I.getParent(), I.getSuccessor(1), 2);
3313 printBranchToBlock(I.getParent(), I.getSuccessor(1), 2);
3318 printPHICopiesForSuccessor(I.getParent(), I.getSuccessor(0), 0);
3319 printBranchToBlock(I.getParent(), I.getSuccessor(0), 0);
3327 void CWriter::visitPHINode(llvm::PHINode &I) {
3332 void CWriter::visitBinaryOperator(llvm::Instruction &I) {
3334 Assert(!I.getType()->isPointerTy());
3336 if (llvm::isa<const llvm::VectorType>(I.getOperand(0)->getType())) {
3337 const char *intrinsic = NULL;
3338 switch (I.getOpcode()) {
3339 case llvm::Instruction::Add:
3340 intrinsic =
"__add";
3342 case llvm::Instruction::FAdd:
3343 intrinsic =
"__add";
3345 case llvm::Instruction::Sub:
3346 intrinsic =
"__sub";
3348 case llvm::Instruction::FSub:
3349 intrinsic =
"__sub";
3351 case llvm::Instruction::Mul:
3352 intrinsic =
"__mul";
3354 case llvm::Instruction::FMul:
3355 intrinsic =
"__mul";
3357 case llvm::Instruction::URem:
3358 intrinsic =
"__urem";
3360 case llvm::Instruction::SRem:
3361 intrinsic =
"__srem";
3363 case llvm::Instruction::FRem:
3364 intrinsic =
"__frem";
3366 case llvm::Instruction::UDiv:
3367 intrinsic =
"__udiv";
3369 case llvm::Instruction::SDiv:
3370 intrinsic =
"__sdiv";
3372 case llvm::Instruction::FDiv:
3373 intrinsic =
"__div";
3375 case llvm::Instruction::And:
3376 intrinsic =
"__and";
3378 case llvm::Instruction::Or:
3381 case llvm::Instruction::Xor:
3382 intrinsic =
"__xor";
3384 case llvm::Instruction::Shl:
3385 intrinsic =
"__shl";
3387 case llvm::Instruction::LShr:
3388 intrinsic =
"__lshr";
3390 case llvm::Instruction::AShr:
3391 intrinsic =
"__ashr";
3395 llvm::errs() <<
"Invalid operator type!" << I;
3397 llvm_unreachable(0);
3401 writeOperand(I.getOperand(0));
3403 if ((I.getOpcode() == llvm::Instruction::Shl || I.getOpcode() == llvm::Instruction::LShr ||
3404 I.getOpcode() == llvm::Instruction::AShr)) {
3405 llvm::Value *splat = NULL;
3409 writeOperand(splat);
3411 Out <<
"__extract_element(";
3412 writeOperand(I.getOperand(1));
3416 writeOperand(I.getOperand(1));
3418 writeOperand(I.getOperand(1));
3424 bool needsCast =
false;
3425 if ((I.getType() == llvm::Type::getInt8Ty(I.getContext())) ||
3426 (I.getType() == llvm::Type::getInt16Ty(I.getContext())) ||
3427 (I.getType() == llvm::Type::getFloatTy(I.getContext()))) {
3430 printType(Out, I.getType(),
false);
3436 #if ISPC_LLVM_VERSION >= ISPC_LLVM_8_0 // LLVM 8.0+ 3438 if (match(&I, m_Neg(llvm::PatternMatch::m_Value(X)))) {
3442 }
else if (match(&I, m_FNeg(llvm::PatternMatch::m_Value(X)))) {
3448 if (llvm::BinaryOperator::isNeg(&I)) {
3450 writeOperand(llvm::BinaryOperator::getNegArgument(llvm::cast<llvm::BinaryOperator>(&I)));
3452 }
else if (llvm::BinaryOperator::isFNeg(&I)) {
3454 writeOperand(llvm::BinaryOperator::getFNegArgument(llvm::cast<llvm::BinaryOperator>(&I)));
3458 else if (I.getOpcode() == llvm::Instruction::FRem) {
3460 if (I.getType() == llvm::Type::getFloatTy(I.getContext()))
3462 else if (I.getType() == llvm::Type::getDoubleTy(I.getContext()))
3466 writeOperand(I.getOperand(0));
3468 writeOperand(I.getOperand(1));
3474 bool NeedsClosingParens = writeInstructionCast(I);
3479 writeOperandWithCast(I.getOperand(0), I.getOpcode());
3481 switch (I.getOpcode()) {
3482 case llvm::Instruction::Add:
3483 case llvm::Instruction::FAdd:
3486 case llvm::Instruction::Sub:
3487 case llvm::Instruction::FSub:
3490 case llvm::Instruction::Mul:
3491 case llvm::Instruction::FMul:
3494 case llvm::Instruction::URem:
3495 case llvm::Instruction::SRem:
3496 case llvm::Instruction::FRem:
3499 case llvm::Instruction::UDiv:
3500 case llvm::Instruction::SDiv:
3501 case llvm::Instruction::FDiv:
3504 case llvm::Instruction::And:
3507 case llvm::Instruction::Or:
3510 case llvm::Instruction::Xor:
3513 case llvm::Instruction::Shl:
3516 case llvm::Instruction::LShr:
3517 case llvm::Instruction::AShr:
3522 llvm::errs() <<
"Invalid operator type!" << I;
3524 llvm_unreachable(0);
3527 writeOperandWithCast(I.getOperand(1), I.getOpcode());
3528 if (NeedsClosingParens)
3539 case llvm::ICmpInst::ICMP_EQ:
3541 case llvm::ICmpInst::ICMP_NE:
3542 return "__not_equal";
3543 case llvm::ICmpInst::ICMP_ULE:
3544 return "__unsigned_less_equal";
3545 case llvm::ICmpInst::ICMP_SLE:
3546 return "__signed_less_equal";
3547 case llvm::ICmpInst::ICMP_UGE:
3548 return "__unsigned_greater_equal";
3549 case llvm::ICmpInst::ICMP_SGE:
3550 return "__signed_greater_equal";
3551 case llvm::ICmpInst::ICMP_ULT:
3552 return "__unsigned_less_than";
3553 case llvm::ICmpInst::ICMP_SLT:
3554 return "__signed_less_than";
3555 case llvm::ICmpInst::ICMP_UGT:
3556 return "__unsigned_greater_than";
3557 case llvm::ICmpInst::ICMP_SGT:
3558 return "__signed_greater_than";
3560 case llvm::FCmpInst::FCMP_ORD:
3562 case llvm::FCmpInst::FCMP_UNO:
3563 return "__unordered";
3564 case llvm::FCmpInst::FCMP_UEQ:
3566 case llvm::FCmpInst::FCMP_UNE:
3567 return "__not_equal";
3568 case llvm::FCmpInst::FCMP_ULT:
3569 return "__less_than";
3570 case llvm::FCmpInst::FCMP_ULE:
3571 return "__less_equal";
3572 case llvm::FCmpInst::FCMP_UGT:
3573 return "__greater_than";
3574 case llvm::FCmpInst::FCMP_UGE:
3575 return "__greater_equal";
3576 case llvm::FCmpInst::FCMP_OEQ:
3578 case llvm::FCmpInst::FCMP_ONE:
3579 return "__not_equal";
3580 case llvm::FCmpInst::FCMP_OLT:
3581 return "__less_than";
3582 case llvm::FCmpInst::FCMP_OLE:
3583 return "__less_equal";
3584 case llvm::FCmpInst::FCMP_OGT:
3585 return "__greater_than";
3586 case llvm::FCmpInst::FCMP_OGE:
3587 return "__greater_equal";
3590 llvm_unreachable(0);
3596 llvm::VectorType *vt = llvm::dyn_cast<llvm::VectorType>(t);
3598 t = vt->getElementType();
3600 switch (t->getTypeID()) {
3601 case llvm::Type::FloatTyID:
3603 case llvm::Type::DoubleTyID:
3605 case llvm::Type::IntegerTyID: {
3606 switch (llvm::cast<llvm::IntegerType>(t)->getBitWidth()) {
3620 llvm_unreachable(0);
3626 void CWriter::visitICmpInst(llvm::ICmpInst &I) {
3627 bool isVector = llvm::isa<llvm::VectorType>(I.getOperand(0)->getType());
3634 writeOperand(I.getOperand(0));
3636 writeOperand(I.getOperand(1));
3643 bool NeedsClosingParens = writeInstructionCast(I);
3648 writeOperandWithCast(I.getOperand(0), I);
3650 switch (I.getPredicate()) {
3651 case llvm::ICmpInst::ICMP_EQ:
3654 case llvm::ICmpInst::ICMP_NE:
3657 case llvm::ICmpInst::ICMP_ULE:
3658 case llvm::ICmpInst::ICMP_SLE:
3661 case llvm::ICmpInst::ICMP_UGE:
3662 case llvm::ICmpInst::ICMP_SGE:
3665 case llvm::ICmpInst::ICMP_ULT:
3666 case llvm::ICmpInst::ICMP_SLT:
3669 case llvm::ICmpInst::ICMP_UGT:
3670 case llvm::ICmpInst::ICMP_SGT:
3675 llvm::errs() <<
"Invalid icmp predicate!" << I;
3677 llvm_unreachable(0);
3680 writeOperandWithCast(I.getOperand(1), I);
3681 if (NeedsClosingParens)
3685 void CWriter::visitFCmpInst(llvm::FCmpInst &I) {
3686 bool isVector = llvm::isa<llvm::VectorType>(I.getOperand(0)->getType());
3688 if (I.getPredicate() == llvm::FCmpInst::FCMP_FALSE) {
3690 llvm::report_fatal_error(
"FIXME: vector FCMP_FALSE");
3695 if (I.getPredicate() == llvm::FCmpInst::FCMP_TRUE) {
3697 llvm::report_fatal_error(
"FIXME: vector FCMP_TRUE");
3710 switch (I.getPredicate()) {
3712 llvm_unreachable(
"Illegal FCmp predicate");
3713 case llvm::FCmpInst::FCMP_ORD:
3716 case llvm::FCmpInst::FCMP_UNO:
3720 case llvm::FCmpInst::FCMP_UEQ:
3723 case llvm::FCmpInst::FCMP_UNE:
3726 case llvm::FCmpInst::FCMP_ULT:
3729 case llvm::FCmpInst::FCMP_ULE:
3732 case llvm::FCmpInst::FCMP_UGT:
3735 case llvm::FCmpInst::FCMP_UGE:
3739 case llvm::FCmpInst::FCMP_OEQ:
3742 case llvm::FCmpInst::FCMP_ONE:
3745 case llvm::FCmpInst::FCMP_OLT:
3748 case llvm::FCmpInst::FCMP_OLE:
3751 case llvm::FCmpInst::FCMP_OGT:
3754 case llvm::FCmpInst::FCMP_OGE:
3759 Out <<
"llvm_fcmp_" << op <<
"(";
3763 writeOperand(I.getOperand(0));
3766 writeOperand(I.getOperand(1));
3771 switch (Ty->getTypeID()) {
3773 llvm_unreachable(
"Invalid Type");
3774 case llvm::Type::FloatTyID:
3776 case llvm::Type::DoubleTyID:
3778 case llvm::Type::IntegerTyID: {
3779 unsigned NumBits = llvm::cast<llvm::IntegerType>(Ty)->getBitWidth();
3788 void CWriter::visitCastInst(llvm::CastInst &I) {
3789 llvm::Type *DstTy = I.getType();
3790 llvm::Type *SrcTy = I.getOperand(0)->getType();
3794 Out << GetValueName(&I) <<
"__BITCAST_TEMPORARY." <<
getFloatBitCastField(I.getOperand(0)->getType()) <<
" = ";
3795 writeOperand(I.getOperand(0));
3796 Out <<
", " << GetValueName(&I) <<
"__BITCAST_TEMPORARY." <<
getFloatBitCastField(I.getType());
3801 if ((llvm::isa<llvm::VectorType>(DstTy)) && (!llvm::isa<llvm::VectorType>(SrcTy))) {
3802 writeOperand(I.getOperand(0));
3807 bool closeParen = printCast(I.getOpcode(), SrcTy, DstTy);
3810 if (SrcTy == llvm::Type::getInt1Ty(I.getContext()) && I.getOpcode() == llvm::Instruction::SExt)
3813 writeOperand(I.getOperand(0));
3815 if (DstTy == llvm::Type::getInt1Ty(I.getContext()) &&
3816 (I.getOpcode() == llvm::Instruction::Trunc || I.getOpcode() == llvm::Instruction::FPToUI ||
3817 I.getOpcode() == llvm::Instruction::FPToSI || I.getOpcode() == llvm::Instruction::PtrToInt)) {
3826 void CWriter::visitSelectInst(llvm::SelectInst &I) {
3827 if (llvm::isa<llvm::VectorType>(I.getType())) {
3829 writeOperand(I.getCondition());
3831 writeOperand(I.getTrueValue());
3833 writeOperand(I.getFalseValue());
3839 writeOperand(I.getCondition());
3841 writeOperand(I.getTrueValue());
3843 writeOperand(I.getFalseValue());
3849 static void printLimitValue(llvm::IntegerType &Ty,
bool isSigned,
bool isMax, llvm::raw_ostream &Out) {
3850 const char *type =
"";
3851 const char *sprefix =
"";
3853 unsigned NumBits = Ty.getBitWidth();
3857 }
else if (NumBits <= 16) {
3859 }
else if (NumBits <= 32) {
3861 }
else if (NumBits <= 64) {
3864 llvm_unreachable(
"Bit widths > 64 not implemented yet");
3868 Out << sprefix << type << (isMax ?
"_MAX" :
"_MIN");
3870 Out <<
"U" << type << (isMax ?
"_MAX" :
"0");
3874 return T.getBitWidth() == 8 || T.getBitWidth() == 16 || T.getBitWidth() == 32 || T.getBitWidth() == 64;
3877 void CWriter::printIntrinsicDefinition(
const llvm::Function &F, llvm::raw_ostream &Out) {
3878 llvm::FunctionType *funT = F.getFunctionType();
3879 llvm::Type *retT = F.getReturnType();
3880 llvm::IntegerType *elemT = llvm::cast<llvm::IntegerType>(funT->getParamType(1));
3883 Assert(llvm::cast<llvm::StructType>(retT)->getElementType(0) == elemT && elemT == funT->getParamType(0) &&
3884 funT->getNumParams() == 2);
3886 switch (F.getIntrinsicID()) {
3888 llvm_unreachable(
"Unsupported Intrinsic.");
3889 case llvm::Intrinsic::uadd_with_overflow:
3896 Out <<
"static inline ";
3897 printType(Out, retT);
3898 Out << GetValueName(&F);
3900 printSimpleType(Out, elemT,
false);
3902 printSimpleType(Out, elemT,
false);
3904 printType(Out, retT);
3906 Out <<
" r.field0 = a + b;\n";
3907 Out <<
" r.field1 = (r.field0 < a);\n";
3908 Out <<
" return r;\n}\n";
3911 case llvm::Intrinsic::sadd_with_overflow:
3920 printType(Out, retT);
3921 Out << GetValueName(&F);
3923 printSimpleType(Out, elemT,
true);
3925 printSimpleType(Out, elemT,
true);
3927 printType(Out, retT);
3929 Out <<
" r.field1 = (b > 0 && a > ";
3931 Out <<
" - b) || (b < 0 && a < ";
3934 Out <<
" r.field0 = r.field1 ? 0 : a + b;\n";
3935 Out <<
" return r;\n}\n";
3938 case llvm::Intrinsic::umul_with_overflow:
3939 Out <<
"static inline ";
3940 printType(Out, retT);
3941 Out << GetValueName(&F);
3943 printSimpleType(Out, elemT,
false);
3945 printSimpleType(Out, elemT,
false);
3948 printType(Out, retT);
3951 unsigned NumBits = llvm::cast<llvm::IntegerType>(elemT)->getBitWidth();
3952 std::stringstream str_type;
3954 str_type <<
"uint" << 2 * NumBits <<
"_t";
3956 Assert(NumBits <= 64 && "Bit widths > 128 not implemented yet
"); 3957 str_type << "llvmUInt128
"; 3960 Out << " " << str_type.str() << " result = (
" << str_type.str() << ") a * (
" << str_type.str() << ") b;\n
"; 3961 Out << " r.field0 = result;\n
"; 3962 Out << " r.field1 = result >>
" << NumBits << ";\n
"; 3963 Out << " return r;\n}\n
"; 3968 void CWriter::lowerIntrinsics(llvm::Function &F) { 3969 // This is used to keep track of intrinsics that get generated to a lowered 3970 // function. We must generate the prototypes before the function body which 3971 // will only be expanded on first use (by the loop below). 3972 std::vector<llvm::Function *> prototypesToGen; 3974 // Examine all the instructions in this function to find the intrinsics that 3975 // need to be lowered. 3976 for (llvm::Function::iterator BB = F.begin(), EE = F.end(); BB != EE; ++BB) 3977 for (llvm::BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E;) 3978 if (llvm::CallInst *CI = llvm::dyn_cast<llvm::CallInst>(I++)) 3979 if (llvm::Function *F = CI->getCalledFunction()) 3980 switch (F->getIntrinsicID()) { 3981 // We directly implement these intrinsics 3982 case llvm::Intrinsic::not_intrinsic: 3983 case llvm::Intrinsic::vastart: 3984 case llvm::Intrinsic::vacopy: 3985 case llvm::Intrinsic::vaend: 3986 case llvm::Intrinsic::returnaddress: 3987 case llvm::Intrinsic::frameaddress: 3988 case llvm::Intrinsic::memset: 3989 case llvm::Intrinsic::prefetch: 3990 case llvm::Intrinsic::powi: 3991 case llvm::Intrinsic::fabs: 3992 case llvm::Intrinsic::x86_sse_cmp_ss: 3993 case llvm::Intrinsic::x86_sse_cmp_ps: 3994 case llvm::Intrinsic::x86_sse2_cmp_sd: 3995 case llvm::Intrinsic::x86_sse2_cmp_pd: 3996 case llvm::Intrinsic::ppc_altivec_lvsl: 3997 case llvm::Intrinsic::uadd_with_overflow: 3998 case llvm::Intrinsic::sadd_with_overflow: 3999 case llvm::Intrinsic::trap: 4000 case llvm::Intrinsic::objectsize: 4001 case llvm::Intrinsic::readcyclecounter: 4002 case llvm::Intrinsic::umul_with_overflow: 4003 // Or we just ignore them because of their uselessness in C++ source 4004 case llvm::Intrinsic::dbg_value: 4005 case llvm::Intrinsic::dbg_declare: 4008 // If this is an intrinsic that directly corresponds to a GCC 4009 // builtin, we handle it. 4010 const char *BuiltinName = ""; 4011 #define GET_GCC_BUILTIN_NAME 4012 #define Intrinsic llvm::Intrinsic 4013 #if ISPC_LLVM_VERSION == ISPC_LLVM_6_0 /* LLVM 6.0 */ 4014 #include "llvm/IR/Intrinsics.gen
" 4015 #else /* LLVM 7.0+ */ 4016 // This looks completely broken, even in 3.2, need to figure out what's going on here 4017 // and how to fix it (if needed). 4018 // #include "llvm/IR/Intrinsics.inc
" 4021 #undef GET_GCC_BUILTIN_NAME 4022 // If we handle it, don't lower it. 4026 // All other intrinsic calls we must lower. 4027 llvm::Instruction *Before = 0; 4028 if (CI != &BB->front()) 4029 Before = &*std::prev(llvm::BasicBlock::iterator(CI)); 4031 IL->LowerIntrinsicCall(CI); 4032 if (Before) { // Move iterator to instruction after call 4033 I = Before->getIterator(); 4038 // If the intrinsic got lowered to another call, and that call has 4039 // a definition then we need to make sure its prototype is emitted 4040 // before any calls to it. 4041 if (llvm::CallInst *Call = llvm::dyn_cast<llvm::CallInst>(I)) 4042 if (llvm::Function *NewF = Call->getCalledFunction()) 4043 if (!NewF->isDeclaration()) 4044 prototypesToGen.push_back(NewF); 4049 // We may have collected some prototypes to emit in the loop above. 4050 // Emit them now, before the function that uses them is emitted. But, 4051 // be careful not to emit them twice. 4052 std::vector<llvm::Function *>::iterator I = prototypesToGen.begin(); 4053 std::vector<llvm::Function *>::iterator E = prototypesToGen.end(); 4054 for (; I != E; ++I) { 4055 if (intrinsicPrototypesAlreadyGenerated.insert(*I).second) { 4057 printFunctionSignature(*I, true); 4063 void CWriter::visitCallInst(llvm::CallInst &I) { 4064 if (llvm::isa<llvm::InlineAsm>(I.getCalledValue())) 4065 return visitInlineAsm(I); 4067 bool WroteCallee = false; 4069 // Handle intrinsic function calls first... 4070 if (llvm::Function *F = I.getCalledFunction()) 4071 if (llvm::Intrinsic::ID ID = (llvm::Intrinsic::ID)F->getIntrinsicID()) 4072 if (visitBuiltinCall(I, ID, WroteCallee)) 4075 llvm::Value *Callee = I.getCalledValue(); 4077 llvm::PointerType *PTy = llvm::cast<llvm::PointerType>(Callee->getType()); 4078 llvm::FunctionType *FTy = llvm::cast<llvm::FunctionType>(PTy->getElementType()); 4080 // If this is a call to a struct-return function, assign to the first 4081 // parameter instead of passing it to the call. 4082 const llvm::AttributeList &PAL = I.getAttributes(); 4084 bool hasByVal = I.hasByValArgument(); 4085 bool isStructRet = (I.getNumArgOperands() > 0) && I.hasStructRetAttr(); 4087 writeOperandDeref(I.getArgOperand(0)); 4095 // If this is an indirect call to a struct return function, we need to cast 4096 // the pointer. Ditto for indirect calls with byval arguments. 4097 bool NeedsCast = (hasByVal || isStructRet) && !llvm::isa<llvm::Function>(Callee); 4099 // GCC is a real PITA. It does not permit codegening casts of functions to 4100 // function pointers if they are in a call (it generates a trap instruction 4101 // instead!). We work around this by inserting a cast to void* in between 4102 // the function and the function pointer cast. Unfortunately, we can't just 4103 // form the constant expression here, because the folder will immediately 4106 // Note finally, that this is completely unsafe. ANSI C does not guarantee 4107 // that void* and function pointers have the same size. :( To deal with this 4108 // in the common case, we handle casts where the number of arguments passed 4111 if (llvm::ConstantExpr *CE = llvm::dyn_cast<llvm::ConstantExpr>(Callee)) 4113 if (llvm::Function *RF = llvm::dyn_cast<llvm::Function>(CE->getOperand(0))) { 4118 if (Callee->getName() == "malloc
" || Callee->getName() == "_aligned_malloc
") 4119 Out << "(uint8_t *)
"; 4121 // This 'if' will fix 'soa-18.ispc' test (fails with optimizations off) 4122 // Yet the way the case is fixed is quite dirty and leads to many other fails 4124 // if (Callee->getName() == "__masked_store_i64
") { 4125 // llvm::CallSite CS(&I); 4126 // llvm::CallSite::arg_iterator AI = CS.arg_begin(); 4127 // if (is_vec16_i64_ty(llvm::cast<llvm::PointerType>((*AI)->getType())->getElementType())) { 4129 // // If we are trying to get a pointer to from a vec16_i64 var 4130 // // It would be better to replace this instruction with a masked copy 4131 // if (llvm::isa<llvm::GetElementPtrInst>(*AI)) { 4132 // writeOperandDeref(*AI); 4133 // Out << " = __select(
"; 4134 // writeOperand(*(AI+2)); 4136 // writeOperand(*(AI+1)); 4138 // writeOperandDeref(*AI); 4146 // Ok, just cast the pointer type. 4149 printStructReturnPointerFunctionType(Out, PAL, 4150 llvm::cast<llvm::PointerType>(I.getCalledValue()->getType())); 4152 printType(Out, I.getCalledValue()->getType(), false, "", true, PAL); 4154 printType(Out, I.getCalledValue()->getType()); 4157 writeOperand(Callee); 4164 bool PrintedArg = false; 4165 if (FTy->isVarArg() && !FTy->getNumParams()) { 4170 unsigned NumDeclaredParams = FTy->getNumParams(); 4171 llvm::CallSite CS(&I); 4172 llvm::CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end(); 4174 if (isStructRet) { // Skip struct return argument. 4179 for (; AI != AE; ++AI, ++ArgNo) { 4182 if (ArgNo == 0 && Callee->getName() == "posix_memalign
") { 4183 // uint8_t** is incompatible with void** without explicit cast. 4184 // Should be do this any other functions? 4186 } else if (ArgNo < NumDeclaredParams && (*AI)->getType() != FTy->getParamType(ArgNo)) { 4188 printType(Out, FTy->getParamType(ArgNo), 4189 PAL.getParamAttributes(ArgNo + 1).hasAttribute(llvm::Attribute::SExt)); 4192 // Check if the argument is expected to be passed by value. 4193 if (I.paramHasAttr(ArgNo, llvm::Attribute::ByVal)) { 4194 writeOperandDeref(*AI); 4206 bool CWriter::visitBuiltinCall(llvm::CallInst &I, llvm::Intrinsic::ID ID, bool &WroteCallee) {
4209 // If this is an intrinsic that directly corresponds to a GCC
4210 // builtin, we emit it here.
4211 const char *BuiltinName = "
"; 4212 #define GET_GCC_BUILTIN_NAME 4213 #define Intrinsic llvm::Intrinsic 4214 #if ISPC_LLVM_VERSION == ISPC_LLVM_6_0 /* LLVM 6.0 */ 4215 #include "llvm/IR/Intrinsics.gen
" 4216 #else /* LLVM 7.0+ */ 4217 // This looks completely broken, even in 3.2, need to figure out what's going on here 4218 // and how to fix it (if needed). 4219 // #include "llvm/IR/Intrinsics.inc
" 4222 #undef GET_GCC_BUILTIN_NAME 4223 Assert(BuiltinName[0] && "Unknown LLVM intrinsic!
"); 4229 // Ignoring debug intrinsics 4230 case llvm::Intrinsic::dbg_value: 4231 case llvm::Intrinsic::dbg_declare: 4233 case llvm::Intrinsic::vastart: 4236 Out << "va_start(*(va_list*)
"; 4237 writeOperand(I.getArgOperand(0)); 4239 // Output the last argument to the enclosing function. 4240 if (I.getParent()->getParent()->arg_empty()) 4241 Out << "vararg_dummy_arg
"; 4243 writeOperand(&*(std::prev(I.getParent()->getParent()->arg_end()))); 4246 case llvm::Intrinsic::vaend: 4247 if (!llvm::isa<llvm::ConstantPointerNull>(I.getArgOperand(0))) { 4248 Out << "0; va_end(*(va_list*)
"; 4249 writeOperand(I.getArgOperand(0)); 4252 Out << "va_end(*(va_list*)0)
"; 4255 case llvm::Intrinsic::vacopy: 4257 Out << "va_copy(*(va_list*)
"; 4258 writeOperand(I.getArgOperand(0)); 4259 Out << ", *(va_list*)
"; 4260 writeOperand(I.getArgOperand(1)); 4263 case llvm::Intrinsic::returnaddress: 4264 Out << "__builtin_return_address(
"; 4265 writeOperand(I.getArgOperand(0)); 4268 case llvm::Intrinsic::frameaddress: 4269 Out << "__builtin_frame_address(
"; 4270 writeOperand(I.getArgOperand(0)); 4273 case llvm::Intrinsic::powi: 4274 Out << "__builtin_powi(
"; 4275 writeOperand(I.getArgOperand(0)); 4277 writeOperand(I.getArgOperand(1)); 4280 case llvm::Intrinsic::fabs: 4281 Out << "__builtin_fabs(
"; 4282 writeOperand(I.getArgOperand(0)); 4285 case llvm::Intrinsic::memset: 4287 writeOperand(I.getArgOperand(0)); 4289 writeOperand(I.getArgOperand(1)); 4291 writeOperand(I.getArgOperand(2)); 4294 case llvm::Intrinsic::prefetch: 4295 Out << "LLVM_PREFETCH((
const void *)
"; 4296 writeOperand(I.getArgOperand(0)); 4298 writeOperand(I.getArgOperand(1)); 4300 writeOperand(I.getArgOperand(2)); 4303 case llvm::Intrinsic::stacksave: 4304 // Emit this as: Val = 0; *((void**)&Val) = __builtin_stack_save() 4305 // to work around GCC bugs (see PR1809). 4306 Out << "0; *((
void**)&
" << GetValueName(&I) << ") = __builtin_stack_save()
"; 4308 case llvm::Intrinsic::x86_sse_cmp_ss: 4309 case llvm::Intrinsic::x86_sse_cmp_ps: 4310 case llvm::Intrinsic::x86_sse2_cmp_sd: 4311 case llvm::Intrinsic::x86_sse2_cmp_pd: 4313 printType(Out, I.getType()); 4315 // Multiple GCC builtins multiplex onto this intrinsic. 4316 switch (llvm::cast<llvm::ConstantInt>(I.getArgOperand(2))->getZExtValue()) { 4318 llvm_unreachable("Invalid
llvm.x86.sse.cmp!
"); 4320 Out << "__builtin_ia32_cmpeq
"; 4323 Out << "__builtin_ia32_cmplt
"; 4326 Out << "__builtin_ia32_cmple
"; 4329 Out << "__builtin_ia32_cmpunord
"; 4332 Out << "__builtin_ia32_cmpneq
"; 4335 Out << "__builtin_ia32_cmpnlt
"; 4338 Out << "__builtin_ia32_cmpnle
"; 4341 Out << "__builtin_ia32_cmpord
"; 4344 if (ID == llvm::Intrinsic::x86_sse_cmp_ps || ID == llvm::Intrinsic::x86_sse2_cmp_pd) 4348 if (ID == llvm::Intrinsic::x86_sse_cmp_ss || ID == llvm::Intrinsic::x86_sse_cmp_ps) 4354 writeOperand(I.getArgOperand(0)); 4356 writeOperand(I.getArgOperand(1)); 4359 case llvm::Intrinsic::ppc_altivec_lvsl: 4361 printType(Out, I.getType()); 4363 Out << "__builtin_altivec_lvsl(0, (
void*)
"; 4364 writeOperand(I.getArgOperand(0)); 4367 case llvm::Intrinsic::uadd_with_overflow: 4368 case llvm::Intrinsic::sadd_with_overflow: 4369 case llvm::Intrinsic::umul_with_overflow: 4370 Out << GetValueName(I.getCalledFunction()) << "(
"; 4371 writeOperand(I.getArgOperand(0)); 4373 writeOperand(I.getArgOperand(1)); 4376 case llvm::Intrinsic::trap: 4379 case llvm::Intrinsic::objectsize: 4381 case llvm::Intrinsic::readcyclecounter: 4387 // TODO: assumptions about what consume arguments from the call are likely wrong 4388 // handle communitivity 4389 void CWriter::visitInlineAsm(llvm::CallInst &CI) { Assert(!"Inline assembly not supported
"); } 4391 void CWriter::visitAllocaInst(llvm::AllocaInst &I) { 4393 printType(Out, I.getType()); 4394 Out << ") alloca(
sizeof(
"; 4395 printType(Out, I.getType()->getElementType()); 4397 if (I.isArrayAllocation()) { 4399 writeOperand(I.getOperand(0)); 4404 void CWriter::printGEPExpression(llvm::Value *Ptr, llvm::gep_type_iterator I, llvm::gep_type_iterator E, bool Static) { 4406 // If there are no indices, just print out the pointer. 4412 // Find out if the last index is into a vector. If so, we have to print this 4413 // specially. Since vectors can't have elements of indexable type, only the 4414 // last index could possibly be of a vector element. 4415 llvm::VectorType *LastIndexIsVector = 0; 4417 for (llvm::gep_type_iterator TmpI = I; TmpI != E; ++TmpI) 4418 LastIndexIsVector = llvm::dyn_cast<llvm::VectorType>(TmpI.getIndexedType()); 4423 // If the last index is into a vector, we can't print it as &a[i][j] because 4424 // we can't index into a vector with j in GCC. Instead, emit this as 4425 // (((float*)&a[i])+j) 4426 if (LastIndexIsVector) { 4428 printType(Out, llvm::PointerType::getUnqual(LastIndexIsVector->getElementType())); 4434 llvm::Type *ParentTy = Ptr->getType(); 4436 // If the first index is 0 (very typical) we can do a number of 4437 // simplifications to clean up the code. 4438 llvm::Value *FirstOp = I.getOperand(); 4439 if (!llvm::isa<llvm::Constant>(FirstOp) || !llvm::cast<llvm::Constant>(FirstOp)->isNullValue()) { 4440 // First index isn't simple, print it the hard way. 4443 ParentTy = I.getIndexedType(); // Skip the zero index. 4446 // Okay, emit the first operand. If Ptr is something that is already address 4447 // exposed, like a global, avoid emitting (&foo)[0], just emit foo instead. 4448 if (isAddressExposed(Ptr)) { 4449 writeOperandInternal(Ptr, Static); 4450 } else if (I != E && I.isStruct()) { 4451 // If we didn't already emit the first operand, see if we can print it as 4452 // P->f instead of "P[0].f
" 4454 Out << "->field
" << llvm::cast<llvm::ConstantInt>(I.getOperand())->getZExtValue(); 4455 ParentTy = I.getIndexedType(); 4456 ++I; // eat the struct index as well. 4458 // Instead of emitting P[0][1], emit (*P)[1], which is more idiomatic. 4465 for (; I != E; ++I) { 4466 if (ParentTy->isStructTy()) { 4467 Out << ".field
" << llvm::cast<llvm::ConstantInt>(I.getOperand())->getZExtValue(); 4468 } else if (ParentTy->isArrayTy()) { 4470 writeOperandWithCast(I.getOperand(), llvm::Instruction::GetElementPtr); 4472 } else if (!ParentTy->isVectorTy()) { 4474 writeOperandWithCast(I.getOperand(), llvm::Instruction::GetElementPtr); 4477 // If the last index is into a vector, then print it out as "+j)
". This 4478 // works with the 'LastIndexIsVector' code above. 4479 if (llvm::isa<llvm::Constant>(I.getOperand()) && 4480 llvm::cast<llvm::Constant>(I.getOperand())->isNullValue()) { 4481 Out << "))
"; // avoid "+0
". 4484 writeOperandWithCast(I.getOperand(), llvm::Instruction::GetElementPtr); 4488 ParentTy = I.getIndexedType(); 4493 void CWriter::writeMemoryAccess(llvm::Value *Operand, llvm::Type *OperandType, bool IsVolatile, unsigned Alignment) { 4494 Assert(!llvm::isa<llvm::VectorType>(OperandType)); 4495 bool IsUnaligned = Alignment && Alignment < TD->getABITypeAlignment(OperandType); 4497 llvm::IntegerType *ITy = llvm::dyn_cast<llvm::IntegerType>(OperandType); 4500 if (IsVolatile || IsUnaligned) { 4502 if (IsUnaligned && ITy && (ITy->getBitWidth() > 64)) 4503 Out << "iN_
" << ITy->getBitWidth() << "_align_
" << Alignment << " *)
"; 4506 Out << "struct __attribute__ ((packed, aligned(
" << Alignment << "))) {
"; 4507 printType(Out, OperandType, false, IsUnaligned ? "data
" : "volatile*
"); 4518 writeOperand(Operand); 4520 if (IsVolatile || IsUnaligned) { 4527 void CWriter::visitLoadInst(llvm::LoadInst &I) { 4528 llvm::VectorType *VT = llvm::dyn_cast<llvm::VectorType>(I.getType()); 4530 Out << "__load<
" << I.getAlignment() << ">(
"; 4531 writeOperand(I.getOperand(0)); 4536 writeMemoryAccess(I.getOperand(0), I.getType(), I.isVolatile(), I.getAlignment()); 4539 void CWriter::visitStoreInst(llvm::StoreInst &I) { 4540 llvm::VectorType *VT = llvm::dyn_cast<llvm::VectorType>(I.getOperand(0)->getType()); 4542 Out << "__store<
" << I.getAlignment() << ">(
"; 4543 writeOperand(I.getOperand(1)); 4545 writeOperand(I.getOperand(0)); 4550 writeMemoryAccess(I.getPointerOperand(), I.getOperand(0)->getType(), I.isVolatile(), I.getAlignment()); 4552 llvm::Value *Operand = I.getOperand(0); 4553 llvm::Constant *BitMask = 0; 4554 if (llvm::IntegerType *ITy = llvm::dyn_cast<llvm::IntegerType>(Operand->getType())) 4555 if (!ITy->isPowerOf2ByteWidth()) 4556 // We have a bit width that doesn't match an even power-of-2 byte 4557 // size. Consequently we must & the value with the type's bit mask 4558 BitMask = llvm::ConstantInt::get(ITy, ITy->getBitMask()); 4561 writeOperand(Operand); 4564 printConstant(BitMask, false); 4569 void CWriter::visitGetElementPtrInst(llvm::GetElementPtrInst &I) { 4570 printGEPExpression(I.getPointerOperand(), gep_type_begin(I), gep_type_end(I), false); 4573 void CWriter::visitVAArgInst(llvm::VAArgInst &I) { 4574 Out << "va_arg(*(va_list*)
"; 4575 writeOperand(I.getOperand(0)); 4577 printType(Out, I.getType()); 4581 void CWriter::visitInsertElementInst(llvm::InsertElementInst &I) { 4583 Type *EltTy = I.getType()->getElementType(); 4584 writeOperand(I.getOperand(0)); 4587 printType(Out, llvm::PointerType::getUnqual(EltTy)); 4588 Out << ")(&
" << GetValueName(&I) << "))[
"; 4589 writeOperand(I.getOperand(2)); 4591 writeOperand(I.getOperand(1)); 4594 writeOperand(I.getOperand(0)); 4596 Out << "__insert_element(&
" << GetValueName(&I) << ",
"; 4597 writeOperand(I.getOperand(2)); 4599 writeOperand(I.getOperand(1)); 4604 void CWriter::visitExtractElementInst(llvm::ExtractElementInst &I) { 4605 // We know that our operand is not inlined. 4609 llvm::cast<llvm::VectorType>(I.getOperand(0)->getType())->getElementType(); 4610 printType(Out, llvm::PointerType::getUnqual(EltTy)); 4611 Out << ")(&
" << GetValueName(I.getOperand(0)) << "))[
"; 4612 writeOperand(I.getOperand(1)); 4615 Out << "(__extract_element(
"; 4616 writeOperand(I.getOperand(0)); 4618 writeOperand(I.getOperand(1)); 4623 void CWriter::visitShuffleVectorInst(llvm::ShuffleVectorInst &SVI) { 4624 printType(Out, SVI.getType()); 4626 llvm::VectorType *VT = SVI.getType(); 4627 unsigned NumElts = VT->getNumElements(); 4628 llvm::Type *EltTy = VT->getElementType(); 4629 llvm::VectorType *OpTy = llvm::dyn_cast<llvm::VectorType>(SVI.getOperand(0)->getType()); 4630 unsigned OpElts = OpTy->getNumElements(); 4632 for (unsigned i = 0; i != NumElts; ++i) { 4635 int SrcVal = SVI.getMaskValue(i); 4636 if ((unsigned)SrcVal >= 2 * OpElts) { 4639 llvm::Value *Op = SVI.getOperand((unsigned)SrcVal >= OpElts); 4640 SrcVal &= OpElts - 1; 4642 if (llvm::isa<llvm::ConstantVector>(Op)) { 4643 printConstant(llvm::cast<llvm::ConstantVector>(Op)->getOperand(SrcVal), false); 4644 } else if (llvm::isa<llvm::ConstantAggregateZero>(Op) || llvm::isa<llvm::UndefValue>(Op)) { 4647 // Do an extractelement of this value from the appropriate input. 4648 Out << " \n#
if defined(KNC) \n
"; 4649 if (OpElts != 1) { // all __vec16_* have overloaded operator [] 4650 Out << "(
" << GetValueName(Op) << ")[
" << SrcVal << "]
"; 4651 } else { // but __vec1_* don't have it 4653 printType(Out, llvm::PointerType::getUnqual(EltTy)); 4654 Out << ")(&
" << GetValueName(Op) << "))[
" << SrcVal << "]
"; 4656 Out << " \n#else \n
"; 4658 printType(Out, llvm::PointerType::getUnqual(EltTy)); 4659 Out << ")(&
" << GetValueName(Op) << "))[
" << SrcVal << "]
"; 4660 Out << " \n#endif \n
"; 4667 void CWriter::visitInsertValueInst(llvm::InsertValueInst &IVI) { 4668 // Start by copying the entire aggregate value into the result variable. 4669 writeOperand(IVI.getOperand(0)); 4672 // Then do the insert to update the field. 4673 Out << GetValueName(&IVI); 4674 for (const unsigned *b = IVI.idx_begin(), *i = b, *e = IVI.idx_end(); i != e; ++i) { 4675 llvm::Type *IndexedTy = 4676 (b == i) ? IVI.getOperand(0)->getType() 4677 : llvm::ExtractValueInst::getIndexedType(IVI.getOperand(0)->getType(), llvm::makeArrayRef(b, i)); 4678 if (IndexedTy->isArrayTy()) 4679 Out << ".array[
" << *i << "]
"; 4681 Out << ".field
" << *i; 4684 writeOperand(IVI.getOperand(1)); 4687 void CWriter::visitExtractValueInst(llvm::ExtractValueInst &EVI) { 4689 if (llvm::isa<llvm::UndefValue>(EVI.getOperand(0))) { 4690 // FIXME: need to handle these--a 0 initializer won't do... 4691 Assert(!llvm::isa<llvm::VectorType>(EVI.getType())); 4693 printType(Out, EVI.getType()); 4696 Out << GetValueName(EVI.getOperand(0)); 4697 for (const unsigned *b = EVI.idx_begin(), *i = b, *e = EVI.idx_end(); i != e; ++i) { 4698 llvm::Type *IndexedTy = (b == i) ? EVI.getOperand(0)->getType() 4699 : llvm::ExtractValueInst::getIndexedType(EVI.getOperand(0)->getType(), 4700 llvm::makeArrayRef(b, i)); 4701 if (IndexedTy->isArrayTy()) 4702 Out << ".array[
" << *i << "]
"; 4704 Out << ".field
" << *i; 4710 void CWriter::visitAtomicRMWInst(llvm::AtomicRMWInst &AI) { 4713 switch (AI.getOperation()) { 4715 llvm_unreachable("Unhandled
case in visitAtomicRMWInst!
"); 4716 case llvm::AtomicRMWInst::Add: 4719 case llvm::AtomicRMWInst::Sub: 4722 case llvm::AtomicRMWInst::Xchg: 4725 case llvm::AtomicRMWInst::And: 4728 case llvm::AtomicRMWInst::Nand: 4731 case llvm::AtomicRMWInst::Or: 4734 case llvm::AtomicRMWInst::Xor: 4737 case llvm::AtomicRMWInst::Min: 4740 case llvm::AtomicRMWInst::Max: 4743 case llvm::AtomicRMWInst::UMin: 4746 case llvm::AtomicRMWInst::UMax: 4751 writeOperand(AI.getOperand(0)); 4753 writeOperand(AI.getOperand(1)); 4757 void CWriter::visitAtomicCmpXchgInst(llvm::AtomicCmpXchgInst &ACXI) { 4759 printType(Out, ACXI.getType(), false); 4760 Out << "::init(
"; // LLVM cmpxchg returns a struct, so we need make an assighment properly 4761 Out << "__atomic_cmpxchg(
"; 4762 writeOperand(ACXI.getPointerOperand()); 4764 writeOperand(ACXI.getCompareOperand()); 4766 writeOperand(ACXI.getNewValOperand()); 4775 class SmearCleanupPass : public llvm::FunctionPass {
4777 SmearCleanupPass(llvm::Module *m, int width) : FunctionPass(ID) {
4779 vectorWidth = width;
4782 llvm::StringRef getPassName() const { return "Smear Cleanup Pass
"; } 4783 bool runOnBasicBlock(llvm::BasicBlock &BB); 4784 bool runOnFunction(llvm::Function &F); 4787 llvm::Module *module; 4788 unsigned int vectorWidth; 4791 unsigned int ChainLength(llvm::InsertElementInst *inst) const; 4792 llvm::Value *getInsertChainSmearValue(llvm::Instruction *inst) const; 4793 llvm::Value *getShuffleSmearValue(llvm::Instruction *inst) const; 4796 char SmearCleanupPass::ID = 0; 4798 unsigned int SmearCleanupPass::ChainLength(llvm::InsertElementInst *inst) const { 4799 unsigned int length = 0; 4800 while (inst != NULL) { 4802 inst = llvm::dyn_cast<llvm::InsertElementInst>(inst->getOperand(0)); 4807 llvm::Value *SmearCleanupPass::getInsertChainSmearValue(llvm::Instruction *inst) const { 4808 // TODO: we don't check indexes where we do insertion, so we may trigger 4809 // transformation for a wrong chain. 4810 // This way of doing broadcast is obsolete and should be probably removed 4813 llvm::InsertElementInst *insertInst = llvm::dyn_cast<llvm::InsertElementInst>(inst); 4818 // We consider only chians of vectorWidth length. 4819 if (ChainLength(insertInst) != vectorWidth) { 4823 // FIXME: we only want to do this to vectors with width equal to 4824 // the target vector width. But we can't easily get that here, so 4825 // for now we at least avoid one case where we definitely don't 4827 llvm::VectorType *vt = llvm::dyn_cast<llvm::VectorType>(insertInst->getType()); 4828 if (vt != NULL && vt->getNumElements() == 1) { 4832 llvm::Value *smearValue = NULL; 4833 while (insertInst != NULL) { 4834 // operand 1 is inserted value 4835 llvm::Value *insertValue = insertInst->getOperand(1); 4836 if (smearValue == NULL) { 4837 smearValue = insertValue; 4838 } else if (smearValue != insertValue) { 4842 // operand 0 is a vector to insert into. 4843 insertInst = llvm::dyn_cast<llvm::InsertElementInst>(insertInst->getOperand(0)); 4845 Assert(smearValue != NULL); 4850 llvm::Value *SmearCleanupPass::getShuffleSmearValue(llvm::Instruction *inst) const { 4851 llvm::ShuffleVectorInst *shuffleInst = llvm::dyn_cast<llvm::ShuffleVectorInst>(inst); 4856 llvm::Constant *mask = llvm::dyn_cast<llvm::Constant>(shuffleInst->getOperand(2)); 4858 // Check that the shuffle is a broadcast of the element of the first vector, 4859 // i.e. mask vector is vector with equal elements of expected size. 4860 if (!(mask && (mask->isNullValue() || (shuffleInst->getMask()->getSplatValue() != 0)) && 4861 llvm::isa<llvm::VectorType>(mask->getType()) && 4862 llvm::dyn_cast<llvm::VectorType>(mask->getType())->getNumElements() == vectorWidth)) { 4866 llvm::InsertElementInst *insertInst = llvm::dyn_cast<llvm::InsertElementInst>(shuffleInst->getOperand(0)); 4868 // Check that it's an InsertElementInst that inserts a value to first element. 4869 if (!(insertInst && llvm::isa<llvm::Constant>(insertInst->getOperand(2)) && 4870 llvm::dyn_cast<llvm::Constant>(insertInst->getOperand(2))->isNullValue())) { 4872 // We can't extract element from vec1 4873 llvm::VectorType *operandVec = llvm::dyn_cast<llvm::VectorType>(shuffleInst->getOperand(0)->getType()); 4874 if (operandVec && operandVec->getNumElements() == 1) 4877 // Insert ExtractElementInstr to get value for smear 4879 llvm::Function *extractFunc = module->getFunction("__extract_element
"); 4881 if (extractFunc == NULL) { 4882 // Declare the __extract_element function if needed; it takes a vector and 4883 // a scalar parameter and returns a scalar of the vector parameter type. 4884 #if ISPC_LLVM_VERSION <= ISPC_LLVM_8_0 4885 llvm::Constant *ef = module->getOrInsertFunction( 4886 "__extract_element
", shuffleInst->getOperand(0)->getType()->getVectorElementType(), 4887 shuffleInst->getOperand(0)->getType(), llvm::IntegerType::get(module->getContext(), 32)); 4888 extractFunc = llvm::dyn_cast<llvm::Function>(ef); 4890 llvm::FunctionCallee ef = module->getOrInsertFunction( 4891 "__extract_element
", shuffleInst->getOperand(0)->getType()->getVectorElementType(), 4892 shuffleInst->getOperand(0)->getType(), llvm::IntegerType::get(module->getContext(), 32)); 4893 extractFunc = llvm::dyn_cast<llvm::Function>(ef.getCallee()); 4895 Assert(extractFunc != NULL); 4896 extractFunc->setDoesNotThrow(); 4897 extractFunc->setOnlyReadsMemory(); 4900 if (extractFunc == NULL) { 4903 llvm::Instruction *extractCall = llvm::ExtractElementInst::Create( 4904 shuffleInst->getOperand(0), mask->getSplatValue(), "__extract_element
", inst); 4908 llvm::Value *result = insertInst->getOperand(1); 4913 bool SmearCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) { 4914 bool modifiedAny = false; 4917 for (llvm::BasicBlock::iterator iter = bb.begin(), e = bb.end(); iter != e; ++iter) { 4918 llvm::Value *smearValue = NULL; 4920 if (!(smearValue = getInsertChainSmearValue(&*iter)) && !(smearValue = getShuffleSmearValue(&*iter))) { 4924 llvm::Type *smearType = smearValue->getType(); 4925 const char *smearFuncName = lGetTypedFunc("smear
", smearType, vectorWidth); 4926 if (smearFuncName != NULL) { 4927 llvm::Function *smearFunc = module->getFunction(smearFuncName); 4928 if (smearFunc == NULL) { 4929 // Declare the smear function if needed; it takes a single 4930 // scalar parameter and returns a vector of the same 4932 #if ISPC_LLVM_VERSION <= ISPC_LLVM_8_0 4933 llvm::Constant *sf = module->getOrInsertFunction(smearFuncName, iter->getType(), smearType); 4934 smearFunc = llvm::dyn_cast<llvm::Function>(sf); 4936 llvm::FunctionCallee sf = module->getOrInsertFunction(smearFuncName, iter->getType(), smearType); 4937 smearFunc = llvm::dyn_cast<llvm::Function>(sf.getCallee()); 4939 Assert(smearFunc != NULL); 4940 smearFunc->setDoesNotThrow(); 4941 smearFunc->setDoesNotAccessMemory(); 4944 Assert(smearFunc != NULL); 4945 llvm::Value *args[1] = {smearValue}; 4946 llvm::ArrayRef<llvm::Value *> argArray(&args[0], &args[1]); 4947 llvm::Instruction *smearCall = llvm::CallInst::Create( 4948 smearFunc, argArray, LLVMGetName(smearValue, "_smear
"), (llvm::Instruction *)NULL); 4950 ReplaceInstWithInst(&*iter, smearCall); 4960 bool SmearCleanupPass::runOnFunction(llvm::Function &F) { 4962 bool modifiedAny = false; 4963 for (llvm::BasicBlock &BB : F) { 4964 modifiedAny |= runOnBasicBlock(BB); 4970 // AndCmpCleanupPass
4972 class AndCmpCleanupPass : public llvm::FunctionPass {
4974 AndCmpCleanupPass() : FunctionPass(ID) {}
4976 llvm::StringRef getPassName() const { return "AndCmp Cleanup Pass
"; } 4977 bool runOnBasicBlock(llvm::BasicBlock &BB); 4978 bool runOnFunction(llvm::Function &F); 4983 char AndCmpCleanupPass::ID = 0; 4985 // Look for ANDs of masks where one of the operands is a vector compare; we 4986 // can turn these into specialized calls to masked vector compares and 4987 // thence eliminate the AND. For example, rather than emitting 4988 // __and(__less(a, b), c), we will emit __less_and_mask(a, b, c). 4989 bool AndCmpCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) { 4990 bool modifiedAny = false; 4993 for (llvm::BasicBlock::iterator iter = bb.begin(), e = bb.end(); iter != e; ++iter) { 4994 // See if we have an AND instruction 4995 llvm::BinaryOperator *bop = llvm::dyn_cast<llvm::BinaryOperator>(&*iter); 4996 if (bop == NULL || bop->getOpcode() != llvm::Instruction::And) 4999 // Make sure it's a vector AND 5000 if (llvm::isa<llvm::VectorType>(bop->getType()) == false) 5003 // We only care about ANDs of the mask type, not, e.g. ANDs of 5005 if (bop->getType() != LLVMTypes::MaskType) 5008 // Now see if either of the operands to the AND is a comparison 5009 for (int i = 0; i < 2; ++i) { 5010 llvm::Value *op = bop->getOperand(i); 5011 llvm::CmpInst *opCmp = llvm::dyn_cast<llvm::CmpInst>(op); 5015 // We have a comparison. However, we also need to make sure 5016 // that it's not comparing two mask values; those can't be 5017 // simplified to something simpler. 5018 if (opCmp->getOperand(0)->getType() == LLVMTypes::MaskType) 5021 // Success! Go ahead and replace the AND with a call to the 5022 // "__and_mask
" variant of the comparison function for this 5024 std::string funcName = lPredicateToString(opCmp->getPredicate()); 5026 funcName += lTypeToSuffix(opCmp->getOperand(0)->getType()); 5027 funcName += "_and_mask
"; 5029 llvm::Function *andCmpFunc = m->module->getFunction(funcName); 5030 if (andCmpFunc == NULL) { 5031 // Declare the function if needed; the first two arguments 5032 // are the same as the two arguments to the compare we're 5033 // replacing and the third argument is the mask type. 5034 llvm::Type *cmpOpType = opCmp->getOperand(0)->getType(); 5035 #if ISPC_LLVM_VERSION <= ISPC_LLVM_8_0 5036 llvm::Constant *acf = m->module->getOrInsertFunction(funcName, LLVMTypes::MaskType, cmpOpType, 5037 cmpOpType, LLVMTypes::MaskType); 5038 andCmpFunc = llvm::dyn_cast<llvm::Function>(acf); 5040 llvm::FunctionCallee acf = m->module->getOrInsertFunction(funcName, LLVMTypes::MaskType, cmpOpType, 5041 cmpOpType, LLVMTypes::MaskType); 5042 andCmpFunc = llvm::dyn_cast<llvm::Function>(acf.getCallee()); 5044 Assert(andCmpFunc != NULL); 5045 andCmpFunc->setDoesNotThrow(); 5046 andCmpFunc->setDoesNotAccessMemory(); 5049 // Set up the function call to the *_and_mask function; the 5050 // mask value passed in is the other operand to the AND. 5051 llvm::Value *args[3] = {opCmp->getOperand(0), opCmp->getOperand(1), bop->getOperand(i ^ 1)}; 5052 llvm::ArrayRef<llvm::Value *> argArray(&args[0], &args[3]); 5053 llvm::Instruction *cmpCall = 5054 llvm::CallInst::Create(andCmpFunc, argArray, LLVMGetName(bop, "_and_mask
"), (llvm::Instruction *)NULL); 5056 // And replace the original AND instruction with it. 5057 llvm::ReplaceInstWithInst(&*iter, cmpCall); 5067 bool AndCmpCleanupPass::runOnFunction(llvm::Function &F) { 5069 bool modifiedAny = false; 5070 for (llvm::BasicBlock &BB : F) { 5071 modifiedAny |= runOnBasicBlock(BB); 5077 // MaskOpsCleanupPass
5085 class MaskOpsCleanupPass : public llvm::FunctionPass {
5087 MaskOpsCleanupPass(llvm::Module *m) : FunctionPass(ID) {
5088 llvm::Type *mt = LLVMTypes::MaskType;
5090 // Declare the __not, __and_not1, and __and_not2 functions that we
5091 // expect the target to end up providing.
5093 #if ISPC_LLVM_VERSION <= ISPC_LLVM_8_0
5094 llvm::dyn_cast<llvm::Function>(m->getOrInsertFunction("__not
", mt, mt)); 5096 llvm::dyn_cast<llvm::Function>(m->getOrInsertFunction("__not
", mt, mt).getCallee()); 5098 Assert(notFunc != NULL); 5099 notFunc->addFnAttr(llvm::Attribute::NoUnwind); 5100 notFunc->addFnAttr(llvm::Attribute::ReadNone); 5103 #if ISPC_LLVM_VERSION <= ISPC_LLVM_8_0 5104 llvm::dyn_cast<llvm::Function>(m->getOrInsertFunction("__and_not1
", mt, mt, mt)); 5106 llvm::dyn_cast<llvm::Function>(m->getOrInsertFunction("__and_not1
", mt, mt, mt).getCallee()); 5108 Assert(andNotFuncs[0] != NULL); 5109 andNotFuncs[0]->addFnAttr(llvm::Attribute::NoUnwind); 5110 andNotFuncs[0]->addFnAttr(llvm::Attribute::ReadNone); 5112 #if ISPC_LLVM_VERSION <= ISPC_LLVM_8_0 5113 llvm::dyn_cast<llvm::Function>(m->getOrInsertFunction("__and_not2
", mt, mt, mt)); 5115 llvm::dyn_cast<llvm::Function>(m->getOrInsertFunction("__and_not2
", mt, mt, mt).getCallee()); 5117 Assert(andNotFuncs[1] != NULL); 5118 andNotFuncs[1]->addFnAttr(llvm::Attribute::NoUnwind); 5119 andNotFuncs[1]->addFnAttr(llvm::Attribute::ReadNone); 5122 llvm::StringRef getPassName() const { return "MaskOps Cleanup Pass
"; } 5123 bool runOnBasicBlock(llvm::BasicBlock &BB); 5124 bool runOnFunction(llvm::Function &F); 5127 llvm::Value *lGetNotOperand(llvm::Value *v) const; 5129 llvm::Function *notFunc, *andNotFuncs[2]; 5134 char MaskOpsCleanupPass::ID = 0; 5139 static bool lIsAllTrue(llvm::Value *v) {
5140 if (llvm::ConstantVector *cv = llvm::dyn_cast<llvm::ConstantVector>(v)) {
5141 llvm::ConstantInt *ci;
5142 return (cv->getSplatValue() != NULL && (ci = llvm::dyn_cast<llvm::ConstantInt>(cv->getSplatValue())) != NULL &&
5146 if (llvm::ConstantDataVector *cdv = llvm::dyn_cast<llvm::ConstantDataVector>(v)) {
5147 llvm::ConstantInt *ci;
5148 return (cdv->getSplatValue() != NULL &&
5149 (ci = llvm::dyn_cast<llvm::ConstantInt>(cdv->getSplatValue())) != NULL && ci->isOne());
5158 llvm::Value *MaskOpsCleanupPass::lGetNotOperand(llvm::Value *v) const {
5159 if (llvm::CallInst *ci = llvm::dyn_cast<llvm::CallInst>(v))
5160 if (ci->getCalledFunction() == notFunc)
5161 // Direct call to __not()
5162 return ci->getArgOperand(0);
5164 if (llvm::BinaryOperator *bop = llvm::dyn_cast<llvm::BinaryOperator>(v))
5165 if (bop->getOpcode() == llvm::Instruction::Xor && lIsAllTrue(bop->getOperand(1)))
5166 // XOR of all-true vector.
5167 return bop->getOperand(0);
5172 bool MaskOpsCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
5173 bool modifiedAny = false;
5176 for (llvm::BasicBlock::iterator iter = bb.begin(), e = bb.end(); iter != e; ++iter) {
5177 llvm::BinaryOperator *bop = llvm::dyn_cast<llvm::BinaryOperator>(&*iter);
5181 if (bop->getType() != LLVMTypes::MaskType)
5184 if (bop->getOpcode() == llvm::Instruction::Xor) {
5185 // Check for XOR with all-true values
5186 if (lIsAllTrue(bop->getOperand(1))) {
5187 llvm::Value *val = bop->getOperand(0);
5188 // Note that ArrayRef takes reference to an object, which must live
5189 // long enough, so passing return value of getOperand directly is
5190 // incorrect and it actually causes crashes with gcc 4.7 and later.
5191 llvm::ArrayRef<llvm::Value *> arg(val);
5192 llvm::CallInst *notCall = llvm::CallInst::Create(notFunc, arg, bop->getName());
5193 ReplaceInstWithInst(&*iter, notCall);
5197 } else if (bop->getOpcode() == llvm::Instruction::And) {
5198 // Check each of the operands to see if they have NOT applied
5200 for (int i = 0; i < 2; ++i) {
5201 if (llvm::Value *notOp = lGetNotOperand(bop->getOperand(i))) {
5202 // In notOp we have the target of the NOT operation;
5203 // put it in its appropriate spot in the operand array.
5204 // Copy in the other operand directly.
5205 llvm::Value *args[2];
5207 args[i ^ 1] = bop->getOperand(i ^ 1);
5208 llvm::ArrayRef<llvm::Value *> argsRef(&args[0], 2);
5210 // Call the appropriate __and_not* function.
5211 llvm::CallInst *andNotCall = llvm::CallInst::Create(andNotFuncs[i], argsRef, bop->getName());
5213 ReplaceInstWithInst(&*iter, andNotCall);
5224 bool MaskOpsCleanupPass::runOnFunction(llvm::Function &F) {
5226 bool modifiedAny = false;
5227 for (llvm::BasicBlock &BB : F) {
5228 modifiedAny |= runOnBasicBlock(BB);
5233 //===----------------------------------------------------------------------===//
5234 // External Interface declaration
5235 //===----------------------------------------------------------------------===//
5237 bool WriteCXXFile(llvm::Module *module, const char *fn, int vectorWidth, const char *includeName) {
5239 llvm::legacy::PassManager pm;
5241 if (const llvm::TargetData *td = targetMachine->getTargetData())
5242 pm.add(new llvm::TargetData(*td));
5244 pm.add(new llvm::TargetData(module));
5247 llvm::sys::fs::OpenFlags flags = llvm::sys::fs::F_None;
5249 std::error_code error;
5251 llvm::ToolOutputFile *of = new llvm::ToolOutputFile(fn, error, flags);
5254 Error(SourcePos(), "
Error opening output file \
"%s\".\n", fn);
5258 llvm::formatted_raw_ostream fos(of->os());
5260 pm.add(llvm::createGCLoweringPass());
5261 pm.add(llvm::createLowerInvokePass());
5262 pm.add(llvm::createCFGSimplificationPass());
5266 pm.add(llvm::createDeadCodeEliminationPass());
5268 pm.add(
new CWriter(fos, includeName, vectorWidth));
static const char * lPredicateToString(llvm::CmpInst::Predicate p)
pointer operator*() const
static bool isFPIntBitCast(const llvm::Instruction &I)
static void findUsedArrayAndLongIntTypes(const llvm::Module *m, std::vector< llvm::ArrayType *> &t, std::vector< llvm::IntegerType *> &i, std::vector< bool > &IsVolatile, std::vector< int > &Alignment)
constant_iterator constant_begin(const llvm::Function *F)
static SpecialGlobalClass getGlobalVariableClass(const llvm::GlobalVariable *GV)
static void PrintEscapedString(const char *Str, unsigned Length, llvm::raw_ostream &Out)
bool operator==(const constant_iterator &x) const
static const char * lGetTypedFunc(const char *base, llvm::Type *matchType, int width)
bool isAtConstant() const
static bool is_vec16_i64_ty(llvm::Type *Ty)
static void FindStaticTors(llvm::GlobalVariable *GV, std::set< llvm::Function *> &StaticTors)
llvm::const_inst_iterator InstI
bool operator!=(const constant_iterator &x) const
static llvm::Type * Int8Type
Header file with declarations for various LLVM utility stuff.
constant_iterator constant_end(const llvm::Function *F)
static const char * getFloatBitCastField(llvm::Type *Ty)
void Error(SourcePos p, const char *fmt,...)
constant_iterator(const llvm::Function *F, bool)
static void generateCompilerSpecificCode(llvm::formatted_raw_ostream &Out, const llvm::DataLayout *TD)
static bool isFPCSafeToPrint(const llvm::ConstantFP *CFP)
static std::string CBEMangle(const std::string &S)
static void printLimitValue(llvm::IntegerType &Ty, bool isSigned, bool isMax, llvm::raw_ostream &Out)
static const char * lTypeToSuffix(llvm::Type *t)
bool LLVMVectorValuesAllEqual(llvm::Value *v, llvm::Value **splat)
static std::string ftostr(const llvm::APFloat &V)
Declaration of the Module class, which is the ispc-side representation of the results of compiling a ...
constant_iterator & operator++()
Main ispc.header file. Defines Target, Globals and Opt classes.
constant_iterator(const llvm::Function *F)
static bool isSupportedIntegerSize(llvm::IntegerType &T)