diff options
author | arphaman <arphaman@gmail.com> | 2013-09-18 15:04:06 +0100 |
---|---|---|
committer | arphaman <arphaman@gmail.com> | 2013-09-18 15:04:06 +0100 |
commit | 30af97c28d5bed8a4e8ba2ef90f6cde1390606ce (patch) | |
tree | 5f42d944f75e30538d67e536ee5918e501bb1053 | |
parent | 6074e7c2442679d7b6b0ba5d7ef288566be90f9e (diff) | |
download | flang-30af97c28d5bed8a4e8ba2ef90f6cde1390606ce.tar.gz |
added codegen for int, real and cmplx array operation intrinsics
-rw-r--r-- | lib/CodeGen/CGArray.cpp | 38 | ||||
-rw-r--r-- | lib/CodeGen/CGArray.h | 1 | ||||
-rw-r--r-- | test/CodeGen/arrayOperations.f95 | 5 | ||||
-rw-r--r-- | test/CodeGenInAction/arrayOperations.f95 | 7 |
4 files changed, 51 insertions, 0 deletions
diff --git a/lib/CodeGen/CGArray.cpp b/lib/CodeGen/CGArray.cpp index cbe4fdb6f3..6871ec9bc6 100644 --- a/lib/CodeGen/CGArray.cpp +++ b/lib/CodeGen/CGArray.cpp @@ -396,6 +396,7 @@ public: void VisitBinaryExpr(const BinaryExpr *E); void VisitArrayConstructorExpr(const ArrayConstructorExpr *E); void VisitArraySectionExpr(const ArraySectionExpr *E); + void VisitIntrinsicCallExpr(const IntrinsicCallExpr *E); const Expr *getLastEmmittedArray() const { return LastArrayEmmitted; @@ -437,6 +438,11 @@ void ScalarEmitterAndSectionGatherer::VisitArraySectionExpr(const ArraySectionEx LastArrayEmmitted = E; } +void ScalarEmitterAndSectionGatherer::VisitIntrinsicCallExpr(const IntrinsicCallExpr *E) { + for(auto I : E->getArguments()) + Emit(I); +} + void ArrayOperation::EmitAllScalarValuesAndArraySections(CodeGenFunction &CGF, const Expr *E) { ScalarEmitterAndSectionGatherer EV(CGF, *this); EV.Emit(E); @@ -561,6 +567,38 @@ RValueTy ArrayOperationEmitter::VisitArraySectionExpr(const ArraySectionExpr *E) return CGF.EmitLoad(Looper.EmitElementPointer(Operation.getArrayValue(E)), ElementType(E)); } +RValueTy ArrayOperationEmitter::VisitIntrinsicCallExpr(const IntrinsicCallExpr *E) { + using namespace intrinsic; + auto Func = getGenericFunctionKind(E->getIntrinsicFunction()); + auto Group = getFunctionGroup(Func); + auto Args = E->getArguments(); + + switch(Group) { + case GROUP_CONVERSION: { + auto FirstVal = Emit(Args[0]); + + if(Func == INT || Func == REAL) + return CGF.EmitImplicitConversion(FirstVal, E->getType()); + else if(Func == CMPLX) { + if(FirstVal.isComplex()) + return CGF.EmitComplexToComplexConversion(FirstVal.asComplex(), + E->getType()); + if(Args.size() >= 2) { + auto ElementType = CGF.getContext().getComplexTypeElementType(E->getType()); + return ComplexValueTy(CGF.EmitScalarToScalarConversion(FirstVal.asScalar(), ElementType), + CGF.EmitScalarToScalarConversion(Emit(Args[1]).asScalar(), ElementType)); + } + else return CGF.EmitScalarToComplexConversion(FirstVal.asScalar(), + E->getType()); + } + break; + } + default: + llvm_unreachable("invalid intrinsic group"); + } + return RValueTy(); +} + LValueTy ArrayOperationEmitter::EmitLValue(const Expr *E) { return Looper.EmitElementPointer(Operation.getArrayValue(E)); } diff --git a/lib/CodeGen/CGArray.h b/lib/CodeGen/CGArray.h index faefc41fe9..50e2c2e3f4 100644 --- a/lib/CodeGen/CGArray.h +++ b/lib/CodeGen/CGArray.h @@ -193,6 +193,7 @@ public: RValueTy VisitBinaryExpr(const BinaryExpr *E); RValueTy VisitArrayConstructorExpr(const ArrayConstructorExpr *E); RValueTy VisitArraySectionExpr(const ArraySectionExpr *E); + RValueTy VisitIntrinsicCallExpr(const IntrinsicCallExpr *E); static QualType ElementType(const Expr *E) { return cast<ArrayType>(E->getType().getTypePtr())->getElementType(); diff --git a/test/CodeGen/arrayOperations.f95 b/test/CodeGen/arrayOperations.f95 index 7f0fe77cc9..c44ce73c0d 100644 --- a/test/CodeGen/arrayOperations.f95 +++ b/test/CodeGen/arrayOperations.f95 @@ -25,4 +25,9 @@ PROGRAM test l_mat = i_mat <= i_mat2 + i_mat = int(r_mat) + r_mat = real(i_mat) + c_mat = cmplx(c_mat2) + c_mat = cmplx(i_mat,r_mat) + END diff --git a/test/CodeGenInAction/arrayOperations.f95 b/test/CodeGenInAction/arrayOperations.f95 index a3069cfdff..439b90ed6d 100644 --- a/test/CodeGenInAction/arrayOperations.f95 +++ b/test/CodeGenInAction/arrayOperations.f95 @@ -47,4 +47,11 @@ program arrayops i_mat(1,3), ', ', i_mat(2,3), ', ', i_mat(3,3) continue ! CHECK-NEXT: 2, 2, 2, 2, 2, 2, 2, 2, 1 + r_mat = 5.5 + i_mat = int(r_mat) + print *, i_mat(1,1), ', ', i_mat(2,1), ', ', i_mat(3,1), ', ', & + i_mat(1,2), ', ', i_mat(2,2), ', ', i_mat(3,2), ', ', & + i_mat(1,3), ', ', i_mat(2,3), ', ', i_mat(3,3) + continue ! CHECK-NEXT: 5, 5, 5, 5, 5, 5, 5, 5, 5 + end |