summaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGSystemLibflang.cpp
blob: 9929e86d0f8fed0740eab9990ce876b6a086712b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
//===----- CGSystemLibflang.cpp - Interface to Libflang System Runtime -----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "CGSystemRuntime.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"

namespace flang {
namespace CodeGen {

class CGLibflangSystemRuntime : public CGSystemRuntime {
public:
  CGLibflangSystemRuntime(CodeGenModule &CGM)
    : CGSystemRuntime(CGM) {
  }

  void EmitInit(CodeGenFunction &CGF);

  llvm::Value *EmitMalloc(CodeGenFunction &CGF, llvm::Value *Size);
  void EmitFree(CodeGenFunction &CGF, llvm::Value *Ptr);

  llvm::Value *EmitETIME(CodeGenFunction &CGF, ArrayRef<Expr*> Arguments);
};

void CGLibflangSystemRuntime::EmitInit(CodeGenFunction &CGF) {
  auto Func = CGM.GetRuntimeFunction("sys_init", ArrayRef<CGType>());
  CallArgList ArgList;
  CGF.EmitCall(Func.getFunction(), Func.getInfo(), ArgList);
}

llvm::Value *CGLibflangSystemRuntime::EmitMalloc(CodeGenFunction &CGF, llvm::Value *Size) {
  auto Func = CGM.GetRuntimeFunction1("malloc", CGM.SizeTy, CGM.VoidPtrTy);
  CallArgList ArgList;
  CGF.EmitCallArg(ArgList, Size, Func.getInfo()->getArguments()[0]);
  return CGF.EmitCall(Func.getFunction(), Func.getInfo(), ArgList).asScalar();
}

void CGLibflangSystemRuntime::EmitFree(CodeGenFunction &CGF, llvm::Value *Ptr) {
  auto Func = CGM.GetRuntimeFunction1("free", CGM.VoidPtrTy);
  CallArgList ArgList;
  CGF.EmitCallArg(ArgList, Ptr->getType() == CGM.VoidPtrTy?
                           Ptr : CGF.getBuilder().CreateBitCast(Ptr, CGM.VoidPtrTy),
                  Func.getInfo()->getArguments()[0]);
  CGF.EmitCall(Func.getFunction(), Func.getInfo(), ArgList);
}

llvm::Value *CGLibflangSystemRuntime::EmitETIME(CodeGenFunction &CGF, ArrayRef<Expr*> Arguments) {
  auto RealTy = CGM.getContext().RealTy;
  auto RealPtrTy = llvm::PointerType::get(CGF.ConvertTypeForMem(RealTy) ,0);
  auto Func = CGM.GetRuntimeFunction2(
    RealTy->getBuiltinTypeKind() == BuiltinType::Real4? "etimef" : "etime",
                                      RealPtrTy, RealPtrTy, RealTy);
  auto Arr = CGF.EmitArrayArgumentPointerValueABI(Arguments[0]);
  CallArgList ArgList;
  CGF.EmitCallArg(ArgList, Arr, Func.getInfo()->getArguments()[0]);
  CGF.EmitCallArg(ArgList,
                  CGF.getBuilder().CreateConstInBoundsGEP1_32(
                    CGF.ConvertTypeForMem(RealTy),Arr, 1, NULL),
                  Func.getInfo()->getArguments()[1]);
  return CGF.EmitCall(Func.getFunction(), Func.getInfo(), ArgList).asScalar();
}

CGSystemRuntime *CreateLibflangSystemRuntime(CodeGenModule &CGM) {
  return new CGLibflangSystemRuntime(CGM);
}

}
} // end namespace flang