From 0eade319cdb72e24c11d068728a98083737c6435 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 24 Mar 2006 02:22:33 +0000 Subject: [PATCH] Lower target intrinsics into an INTRINSIC node git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27035 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 84 ++++++++++++++++++- 1 file changed, 80 insertions(+), 4 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index b579ebf837a..30871dd4e11 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -481,6 +481,7 @@ public: void visitCall(CallInst &I); void visitInlineAsm(CallInst &I); const char *visitIntrinsicCall(CallInst &I, unsigned Intrinsic); + void visitTargetIntrinsic(CallInst &I, unsigned Intrinsic); void visitVAStart(CallInst &I); void visitVAArg(VAArgInst &I); @@ -1001,12 +1002,91 @@ void SelectionDAGLowering::visitStore(StoreInst &I) { DAG.getSrcValue(I.getOperand(1)))); } +/// IntrinsicCannotAccessMemory - Return true if the specified intrinsic cannot +/// access memory and has no other side effects at all. +static bool IntrinsicCannotAccessMemory(unsigned IntrinsicID) { +#define GET_NO_MEMORY_INTRINSICS +#include "llvm/Intrinsics.gen" +#undef GET_NO_MEMORY_INTRINSICS + return false; +} + +/// visitTargetIntrinsic - Lower a call of a target intrinsic to an INTRINSIC +/// node. +void SelectionDAGLowering::visitTargetIntrinsic(CallInst &I, + unsigned Intrinsic) { + bool HasChain = IntrinsicCannotAccessMemory(Intrinsic); + + // Build the operand list. + std::vector Ops; + if (HasChain) // If this intrinsic has side-effects, chainify it. + Ops.push_back(getRoot()); + + // Add the intrinsic ID as an integer operand. + Ops.push_back(DAG.getConstant(Intrinsic, TLI.getPointerTy())); + + // Add all operands of the call to the operand list. + for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) { + SDOperand Op = getValue(I.getOperand(i)); + + // If this is a vector type, force it to the right packed type. + if (Op.getValueType() == MVT::Vector) { + const PackedType *OpTy = cast(I.getOperand(i)->getType()); + MVT::ValueType EltVT = TLI.getValueType(OpTy->getElementType()); + + MVT::ValueType VVT = MVT::getVectorType(EltVT, OpTy->getNumElements()); + assert(VVT != MVT::Other && "Intrinsic uses a non-legal type?"); + Op = DAG.getNode(ISD::VBIT_CONVERT, VVT, Op); + } + + assert(TLI.isTypeLegal(Op.getValueType()) && + "Intrinsic uses a non-legal type?"); + Ops.push_back(Op); + } + + std::vector VTs; + if (I.getType() != Type::VoidTy) { + MVT::ValueType VT = TLI.getValueType(I.getType()); + if (VT == MVT::Vector) { + const PackedType *DestTy = cast(I.getType()); + MVT::ValueType EltVT = TLI.getValueType(DestTy->getElementType()); + + VT = MVT::getVectorType(EltVT, DestTy->getNumElements()); + assert(VT != MVT::Other && "Intrinsic uses a non-legal type?"); + } + + assert(TLI.isTypeLegal(VT) && "Intrinsic uses a non-legal type?"); + VTs.push_back(VT); + } + if (HasChain) + VTs.push_back(MVT::Other); + + // Create the node. + SDOperand Result = DAG.getNode(ISD::INTRINSIC, VTs, Ops); + + if (HasChain) + DAG.setRoot(Result.getValue(Result.Val->getNumValues()-1)); + if (I.getType() != Type::VoidTy) { + if (const PackedType *PTy = dyn_cast(I.getType())) { + MVT::ValueType EVT = TLI.getValueType(PTy->getElementType()); + Result = DAG.getNode(ISD::VBIT_CONVERT, MVT::Vector, Result, + DAG.getConstant(PTy->getNumElements(), MVT::i32), + DAG.getValueType(EVT)); + } + setValue(&I, Result); + } +} + /// visitIntrinsicCall - Lower the call to the specified intrinsic function. If /// we want to emit this as a call to a named external function, return the name /// otherwise lower it and return null. const char * SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { switch (Intrinsic) { + default: + // By default, turn this into a target intrinsic node. + visitTargetIntrinsic(I, Intrinsic); + return 0; case Intrinsic::vastart: visitVAStart(I); return 0; case Intrinsic::vaend: visitVAEnd(I); return 0; case Intrinsic::vacopy: visitVACopy(I); return 0; @@ -1194,10 +1274,6 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { case Intrinsic::prefetch: // FIXME: Currently discarding prefetches. return 0; - default: - std::cerr << I; - assert(0 && "This intrinsic is not implemented yet!"); - return 0; } } -- 2.34.1