1fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard//===-- R600KernelParameters.cpp - Lower kernel function arguments --------===//
2a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//
3a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//                     The LLVM Compiler Infrastructure
4a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//
5a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// This file is distributed under the University of Illinois Open Source
6a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// License. See LICENSE.TXT for details.
7a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//
8a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//===----------------------------------------------------------------------===//
9a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//
10fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard// This pass lowers kernel function arguments to loads from the vertex buffer.
11fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard//
12fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard// Kernel arguemnts are stored in the vertex buffer at an offset of 9 dwords,
13fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard// so arg0 needs to be loaded from VTX_BUFFER[9] and arg1 is loaded from
14fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard// VTX_BUFFER[10], etc.
15a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//
16a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//===----------------------------------------------------------------------===//
17a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
18fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard#include "AMDGPU.h"
19fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard#include "AMDIL.h"
20fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard#include "llvm/CodeGen/MachineFunctionPass.h"
21a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/Constants.h"
22fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard#include "llvm/Function.h"
23a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/Intrinsics.h"
24fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard#include "llvm/Metadata.h"
25fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard#include "llvm/Module.h"
26fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard#include "llvm/Target/TargetData.h"
27a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/Support/IRBuilder.h"
28a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/Support/TypeBuilder.h"
29a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
30a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include <map>
31a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include <set>
32a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
33a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardusing namespace llvm;
34fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
35fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellardnamespace {
36a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
37a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#define CONSTANT_CACHE_SIZE_DW 127
38a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
39f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellardclass R600KernelParameters : public FunctionPass {
40f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard  const TargetData *TD;
41a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  LLVMContext* Context;
42f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard  Module *Mod;
43fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
44f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard  struct Param {
45f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard    Param() : Val(NULL), PtrVal(NULL), OffsetInDW(0), SizeInDW(0),
46f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard              IsIndirect(true), SpecialID(0) {}
47fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
48f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard    Value* Val;
49f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard    Value* PtrVal;
50f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard    int OffsetInDW;
51f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard    int SizeInDW;
52a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
53f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard    bool IsIndirect;
54fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
55f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard    std::string SpecialType;
56f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard    int SpecialID;
57fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
58f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard    int End() { return OffsetInDW + SizeInDW; }
59fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    // The first 9 dwords are reserved for the grid sizes.
60f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard    int getRatOffset() { return 9 + OffsetInDW; }
61a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  };
62a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
63f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard  std::vector<Param> Params;
64a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
65f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard  bool IsOpenCLKernel(const Function *Fun);
66fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  int getLastSpecialID(const std::string& TypeName);
67fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
68a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  int getListSize();
69f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard  void AddParam(Argument *Arg);
70f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard  int CalculateArgumentSize(Argument *Arg);
71f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard  void RunAna(Function *Fun);
72f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard  void Replace(Function *Fun);
73f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard  bool IsIndirect(Value *Val, std::set<Value*> &Visited);
74f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard  void Propagate(Function* Fun);
75f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard  void Propagate(Value *V, const Twine &Name, bool IsIndirect = true);
76f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard  Value* ConstantRead(Function *Fun, Param &P);
77f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard  Value* handleSpecial(Function *Fun, Param &P);
78f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard  bool IsSpecialType(Type *T);
79f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard  std::string getSpecialTypeName(Type *T);
80a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardpublic:
81a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  static char ID;
82a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  R600KernelParameters() : FunctionPass(ID) {};
83fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  R600KernelParameters(const TargetData* TD) : FunctionPass(ID), TD(TD) {}
84fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  bool runOnFunction (Function &F);
85a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  void getAnalysisUsage(AnalysisUsage &AU) const;
86a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  const char *getPassName() const;
87a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  bool doInitialization(Module &M);
88a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  bool doFinalization(Module &M);
89a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard};
90a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
91a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardchar R600KernelParameters::ID = 0;
92a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
93fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellardstatic RegisterPass<R600KernelParameters> X("kerparam",
94fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard                            "OpenCL Kernel Parameter conversion", false, false);
95