<commit_before>// Copyright <NAME> 2016, 2017

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// For doc, please see the corresponding include file, patch_hostside.h

#include "patch_hostside.h"

#include "cocl_logging.h"

#include "mutations.h"
#include "struct_clone.h"
// #include "ir-to-opencl-common.h"
#include "argparsecpp.h"
#include "type_dumper.h"
#include "GlobalNames.h"
#include "EasyCL/util/easycl_stringhelper.h"

#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/STLExtras.h"

#include "llvm/IR/AssemblyAnnotationWriter.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/LLVMContext.h"
// #include "llvm/IR/IRBuilder.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/DebugInfoMetadata.h"

#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_os_ostream.h"

#include "llvm/Transforms/Utils/BasicBlockUtils.h"

#include <cstdio>
#include <cstdlib>
#include <vector>
#include <map>
#include <set>
#include <stdexcept>
#include <memory>
#include <sstream>
#include <fstream>

using namespace llvm;
using namespace std;
using namespace cocl;

namespace cocl {

static llvm::LLVMContext context;
// static std::string sourcecode_stringname;
static std::string devicellcode_stringname;
static string devicellfilename;

static GlobalNames globalNames;
static TypeDumper typeDumper(&globalNames);
static StructCloner structCloner(&typeDumper, &globalNames);

// static string deviceclfilename;
// static string clfilenamesimple;

// bool single_precision = true;

// this should probably be more of an instance variable probably?
static std::unique_ptr<LaunchCallInfo> launchCallInfo(new LaunchCallInfo);

std::unique_ptr<GenericCallInst> GenericCallInst::create(llvm::InvokeInst *inst) {
    return unique_ptr<GenericCallInst>(new GenericCallInst_Invoke(inst));
}
std::unique_ptr<GenericCallInst> GenericCallInst::create(llvm::CallInst *inst) {
    return unique_ptr<GenericCallInst>(new GenericCallInst_Call(inst));
}

std::ostream &operator<<(std::ostream &os, const LaunchCallInfo &info) {
    raw_os_ostream my_raw_os_ostream(os);
    my_raw_os_ostream << "LaunchCallInfo " << info.kernelName;
    my_raw_os_ostream << "<<<";

    my_raw_os_ostream << ">>>";
    my_raw_os_ostream << "(";
    int i = 0;
    // for(auto it=info.callTypes.begin(); it != info.callTypes.end(); it++) {
    for(auto it=info.params.begin(); it != info.params.end(); it++) {
        if(i > 0){
            my_raw_os_ostream << ", ";
        }
        ParamInfo paramInfo = *it;
        // Type *type = *it;
        paramInfo.type->print(my_raw_os_ostream);
        i++;
    }
    my_raw_os_ostream << ");\n";
    my_raw_os_ostream << "value types: ";
    i = 0;
    for(auto it=info.params.begin(); it != info.params.end(); it++) {
    // for(auto it=info.callValuesByValue.begin(); it != info.callValuesByValue.end(); it++) {
        ParamInfo paramInfo = *it;
        Value *value = paramInfo.value;
        // Value *value = *it;
        if(i > 0) {
            my_raw_os_ostream << ", ";
        }
        my_raw_os_ostream << typeDumper.dumpType(value->getType());
        i ++;
    }
    return os;
}

void PatchHostside::getLaunchTypes(GenericCallInst *inst, LaunchCallInfo *info) {
    // input to this is a cudaLaunch instruction
    // sideeffect is to populate in info:
    // - name of the kernel
    // - type of each of the kernel parameters (without the actual Value's)
    // info->callTypes.clear();
    // outs() << "getLaunchTypes()\n";
    Indentor indentor;
    Value *argOperand = inst->getArgOperand(0);
    int i = 0;
    indentor << "getLaunchTypes" << endl;
    if(ConstantExpr *expr = dyn_cast<ConstantExpr>(argOperand)) {
        Instruction *instr = expr->getAsInstruction();
        Type *op0type = instr->getOperand(0)->getType();
        Type *op0typepointed = op0type->getPointerElementType();
        if(FunctionType *fn = dyn_cast<FunctionType>(op0typepointed)) {
            for(auto it=fn->param_begin(); it != fn->param_end(); it++) {
                Type * paramType = *it;
                indentor << "  fn param type " << typeDumper.dumpType(paramType) << endl;
                // info->callTypes.push_back(paramType);
                info->params[i].type = paramType;
            }
        }
        info->kernelName = instr->getOperand(0)->getName();
        // outs() << "got kernel name " << info->kernelName << "\n";
    } else {
        throw std::runtime_error("getlaunchtypes, didnt get ConstantExpr");
    }
    i++;
}

void PatchHostside::getLaunchArgValue(GenericCallInst *inst, LaunchCallInfo *info, ParamInfo *paramInfo) {<commit_msg>small but important bug in retrieving function parameter types<commit_after>// Copyright <NAME> 2016, 2017

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// For doc, please see the corresponding include file, patch_hostside.h

#include "patch_hostside.h"

#include "cocl_logging.h"

#include "mutations.h"
#include "struct_clone.h"
// #include "ir-to-opencl-common.h"
#include "argparsecpp.h"
#include "type_dumper.h"
#include "GlobalNames.h"
#include "EasyCL/util/easycl_stringhelper.h"

#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/STLExtras.h"

#include "llvm/IR/AssemblyAnnotationWriter.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/LLVMContext.h"
// #include "llvm/IR/IRBuilder.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/DebugInfoMetadata.h"

#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_os_ostream.h"

#include "llvm/Transforms/Utils/BasicBlockUtils.h"

#include <cstdio>
#include <cstdlib>
#include <vector>
#include <map>
#include <set>
#include <stdexcept>
#include <memory>
#include <sstream>
#include <fstream>

using namespace llvm;
using namespace std;
using namespace cocl;

namespace cocl {

static llvm::LLVMContext context;
// static std::string sourcecode_stringname;
static std::string devicellcode_stringname;
static string devicellfilename;

static GlobalNames globalNames;
static TypeDumper typeDumper(&globalNames);
static StructCloner structCloner(&typeDumper, &globalNames);

// static string deviceclfilename;
// static string clfilenamesimple;

// bool single_precision = true;

// this should probably be more of an instance variable probably?
static std::unique_ptr<LaunchCallInfo> launchCallInfo(new LaunchCallInfo);

std::unique_ptr<GenericCallInst> GenericCallInst::create(llvm::InvokeInst *inst) {
    return unique_ptr<GenericCallInst>(new GenericCallInst_Invoke(inst));
}
std::unique_ptr<GenericCallInst> GenericCallInst::create(llvm::CallInst *inst) {
    return unique_ptr<GenericCallInst>(new GenericCallInst_Call(inst));
}

std::ostream &operator<<(std::ostream &os, const LaunchCallInfo &info) {
    raw_os_ostream my_raw_os_ostream(os);
    my_raw_os_ostream << "LaunchCallInfo " << info.kernelName;
    my_raw_os_ostream << "<<<";

    my_raw_os_ostream << ">>>";
    my_raw_os_ostream << "(";
    int i = 0;
    // for(auto it=info.callTypes.begin(); it != info.callTypes.end(); it++) {
    for(auto it=info.params.begin(); it != info.params.end(); it++) {
        if(i > 0){
            my_raw_os_ostream << ", ";
        }
        ParamInfo paramInfo = *it;
        // Type *type = *it;
        paramInfo.type->print(my_raw_os_ostream);
        i++;
    }
    my_raw_os_ostream << ");\n";
    my_raw_os_ostream << "value types: ";
    i = 0;
    for(auto it=info.params.begin(); it != info.params.end(); it++) {
    // for(auto it=info.callValuesByValue.begin(); it != info.callValuesByValue.end(); it++) {
        ParamInfo paramInfo = *it;
        Value *value = paramInfo.value;
        // Value *value = *it;
        if(i > 0) {
            my_raw_os_ostream << ", ";
        }
        my_raw_os_ostream << typeDumper.dumpType(value->getType());
        i ++;
    }
    return os;
}

void PatchHostside::getLaunchTypes(GenericCallInst *inst, LaunchCallInfo *info) {
    // input to this is a cudaLaunch instruction
    // sideeffect is to populate in info:
    // - name of the kernel
    // - type of each of the kernel parameters (without the actual Value's)
    // info->callTypes.clear();
    // outs() << "getLaunchTypes()\n";
    Indentor indentor;
    Value *argOperand = inst->getArgOperand(0);
    indentor << "getLaunchTypes" << endl;
    if(ConstantExpr *expr = dyn_cast<ConstantExpr>(argOperand)) {
        Instruction *instr = expr->getAsInstruction();
        Type *op0type = instr->getOperand(0)->getType();
        Type *op0typepointed = op0type->getPointerElementType();
        if(FunctionType *fn = dyn_cast<FunctionType>(op0typepointed)) {
            int i = 0;
            for(auto it=fn->param_begin(); it != fn->param_end(); it++) {
                Type * paramType = *it;
                indentor << "  fn param type[" << i << "] " << typeDumper.dumpType(paramType) << endl;
                // info->callTypes.push_back(paramType);
                info->params[i].type = paramType;
                paramType->dump();
                i++;
            }
        }
        info->kernelName = instr->getOperand(0)->getName();
        // outs() << "got kernel name " << info->kernelName << "\n";
    } else {
        throw std::runtime_error("getlaunchtypes, didnt get ConstantExpr");
    }
}

void PatchHostside::getLaunchArgValue(GenericCallInst *inst, LaunchCallInfo *info, ParamInfo *paramInfo) {
{'fraction_non_alphanumeric': 0.13877285807110368, 'fraction_numerical': 0.004455583402951824, 'mean_word_length': 3.606241983753741, 'pattern_counts': {'":': 0, '<': 127, '<?xml version=': 0, '>': 80, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1422866', 'n_tokens_mistral': 3455, 'n_tokens_neox': 3401, 'n_words': 820}