<commit_before>// Copyright <NAME> 2016

// 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.

#include "struct_clone.h"

#include "ir-to-opencl-common.h"
#include "EasyCL/util/easycl_stringhelper.h"
#include "mutations.h"

#include "llvm/Support/raw_os_ostream.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"

#include <map>
#include <set>

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

namespace cocl {

// static std::map<Type *, Type *> pointerlessTypeByOriginalType;

// extern std::set<string> declaredStructs;
// extern std::string declarations_to_write;
// extern bool single_precision;

// StructType *StructCloner::cloneNoPointers(StructType *inStructType) {

// }

// Type *cloneStructTypeNoPointers(StructType *inType) {

llvm::StructType *StructCloner::createGlobalizedPointerStruct(std::map<llvm::StructType *, llvm::StructType *> &newByOld, llvm::StructType *inType) {
    LLVMContext &context = inType->getContext();
    if(newByOld.find(inType) != newByOld.end()) {
        return newByOld[inType];
    }
    string newName = inType->getName().str() + "_ptrglobal";
    vector<Type *>newChildren;
    for(auto it=inType->element_begin(); it != inType->element_end(); it++) {
        Type *childType = *it;
        if(StructType *childStructType = dyn_cast<StructType>(childType)) {
            childType = createGlobalizedPointerStruct(newByOld, childStructType);
            newChildren.push_back(childType);
        } else if(PointerType *ptr = dyn_cast<PointerType>(childType)) {
            Type *elementType = ptr->getElementType();
            // assume fundamental for now
            if(elementType->getPrimitiveSizeInBits() > 0) {
                PointerType *newPtr = PointerType::get(elementType, 1);
                newChildren.push_back(newPtr);
            } else {
                // just ignore...
                // elementType->dump();
                // throw runtime_error("not implemented");
            }
        } else {
            newChildren.push_back(childType);
        }
    }
    // outs() << "newchildren.size() " << newChildren.size() << "\n";
    StructType *newType = 0;
    if(newChildren.size() > 0) {
        newType = StructType::create(ArrayRef<Type *>(&newChildren[0], &newChildren[newChildren.size()]), newName);
    } else {
        newType = StructType::get(context);
    }
    newByOld[inType] = newType;
    return newType;
}

StructType *StructCloner::cloneNoPointers(StructType *inType) {
    LLVMContext &context = inType->getContext();
    if(pointerlessTypeByOriginalType.find(inType) != pointerlessTypeByOriginalType.end()) {
        return pointerlessTypeByOriginalType[inType];
    }
    // string name = globalNames->getName(inType);
    // string newName = name + "_nopointers";
    string newName = inType->getName().str() + "_nopointers";
    vector<Type *>newChildren;
    for(auto it=inType->element_begin(); it != inType->element_end(); it++) {
        Type *childType = *it;
        if(StructType *childStructType = dyn_cast<StructType>(childType)) {
            childType = cloneNoPointers(childStructType);
            newChildren.push_back(childType);
        } else if(isa<PointerType>(childType)) {
            // ignore
        } else {
            newChildren.push_back(childType);
        }
    }
    // outs() << "newchildren.size() " << newChildren.size() << "\n";
    StructType *newType = 0;
    if(newChildren.size() > 0) {
        newType = StructType::create(ArrayRef<Type *>(&newChildren[0], &newChildren[newChildren.size()]), newName);
    } else {
        newType = StructType::get(context);
    }
    pointerlessTypeByOriginalType[inType] = newType;
    return newType;
}

std::string StructCloner::writeClCopyNoPtrToPtrfull(llvm::StructType *ptrfullType,  std::string srcName, std::string destName) {
    string gencode = "";
    int srcidx = 0;
    int dstidx = 0;
    // outs() << "writeStructCopyCodeNoPointers " << dumpType(structType) << "\n";
    for(auto it=ptrfullType->element_begin(); it != ptrfullType->element_end(); it++) {
        Type *childType = *it;
        if(isa<PointerType>(childType)) {
            // ignore
            // srcidx++;
            dstidx++;
            continue;
        }
        string childSrcName = srcName + ".f" + easycl::toString(srcidx);
        string childDstName = destName + ".f" + easycl::toString(dstidx);
        if(StructType *childStructType = dyn_cast<StructType>(childType)) {
            gencode += writeClCopyNoPtrToPtrfull(childStructType, childSrcName, childDstName);
            srcidx++;
            dstidx++;
        } else if(childType->getPrimitiveSizeInBits() > 0 ) {
            gencode += childDstName + " = " + childSrcName + ";\n";
            // outs() << "copying " << dumpType(childType) << "\n";
            srcidx++;
            dstidx++;
        } else if(ArrayType *arrayType = dyn_cast<ArrayType>(childType)) {
            int numElements = arrayType->getNumElements();
            // outs() << "numlemenets " << numElements << "\n";
            for(int i=0; i < numElements; i++) {
                gencode += childDstName + "[" + easycl::toString(i) + "] = " + childSrcName + "[" + easycl::toString(i) +  "];\n";
            }
            srcidx++;
            dstidx++;
            // throw runtime_error("unhandled type " + dumpType(childType));
        } else {
            outs() << "unhandled type\n";
            childType->dump();
            outs() << "\n";
            // outs() << "unhandled type " + dumpType(childType) << "\n";
            throw runtime_error("unhandled type");
            srcidx++;
            dstidx++;<commit_msg>I think this fixes argmax, in eigen, at least for the simplest cases<commit_after>// Copyright <NAME> 2016

// 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.

#include "struct_clone.h"

#include "ir-to-opencl-common.h"
#include "EasyCL/util/easycl_stringhelper.h"
#include "mutations.h"

#include "llvm/Support/raw_os_ostream.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"

#include <map>
#include <set>

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

namespace cocl {

// static std::map<Type *, Type *> pointerlessTypeByOriginalType;

// extern std::set<string> declaredStructs;
// extern std::string declarations_to_write;
// extern bool single_precision;

// StructType *StructCloner::cloneNoPointers(StructType *inStructType) {

// }

// Type *cloneStructTypeNoPointers(StructType *inType) {

llvm::StructType *StructCloner::createGlobalizedPointerStruct(std::map<llvm::StructType *, llvm::StructType *> &newByOld, llvm::StructType *inType) {
    LLVMContext &context = inType->getContext();
    if(newByOld.find(inType) != newByOld.end()) {
        return newByOld[inType];
    }
    string newName = inType->getName().str() + "_ptrglobal";
    vector<Type *>newChildren;
    for(auto it=inType->element_begin(); it != inType->element_end(); it++) {
        Type *childType = *it;
        if(StructType *childStructType = dyn_cast<StructType>(childType)) {
            childType = createGlobalizedPointerStruct(newByOld, childStructType);
            newChildren.push_back(childType);
        } else if(PointerType *ptr = dyn_cast<PointerType>(childType)) {
            Type *elementType = ptr->getElementType();
            // assume fundamental for now
            if(elementType->getPrimitiveSizeInBits() > 0) {
                PointerType *newPtr = PointerType::get(elementType, 1);
                newChildren.push_back(newPtr);
            } else {
                // just ignore...
                // elementType->dump();
                // throw runtime_error("not implemented");
            }
        } else {
            newChildren.push_back(childType);
        }
    }
    // outs() << "newchildren.size() " << newChildren.size() << "\n";
    StructType *newType = 0;
    if(newChildren.size() > 0) {
        newType = StructType::create(ArrayRef<Type *>(&newChildren[0], &newChildren[newChildren.size()]), newName);
    } else {
        newType = StructType::get(context);
    }
    newByOld[inType] = newType;
    return newType;
}

StructType *StructCloner::cloneNoPointers(StructType *inType) {
    LLVMContext &context = inType->getContext();
    if(pointerlessTypeByOriginalType.find(inType) != pointerlessTypeByOriginalType.end()) {
        return pointerlessTypeByOriginalType[inType];
    }
    // string name = globalNames->getName(inType);
    // string newName = name + "_nopointers";
    string newName = inType->getName().str() + "_nopointers";
    vector<Type *>newChildren;
    for(auto it=inType->element_begin(); it != inType->element_end(); it++) {
        Type *childType = *it;
        if(StructType *childStructType = dyn_cast<StructType>(childType)) {
            childType = cloneNoPointers(childStructType);
            newChildren.push_back(childType);
        } else if(isa<PointerType>(childType)) {
            // ignore
        } else {
            newChildren.push_back(childType);
        }
    }
    // outs() << "newchildren.size() " << newChildren.size() << "\n";
    StructType *newType = 0;
    if(newChildren.size() > 0) {
        newType = StructType::create(ArrayRef<Type *>(&newChildren[0], &newChildren[newChildren.size()]), newName);
    } else {
        newType = StructType::get(context);
    }
    pointerlessTypeByOriginalType[inType] = newType;
    return newType;
}

std::string StructCloner::writeClCopyNoPtrToPtrfull(llvm::StructType *ptrfullType,  std::string srcName, std::string destName) {
    string gencode = "";
    int srcidx = 0;
    int dstidx = 0;
    // outs() << "writeStructCopyCodeNoPointers " << dumpType(structType) << "\n";
    for(auto it=ptrfullType->element_begin(); it != ptrfullType->element_end(); it++) {
        Type *childType = *it;
        string childSrcName = srcName + ".f" + easycl::toString(srcidx);
        string childDstName = destName + ".f" + easycl::toString(dstidx);
        if(isa<PointerType>(childType)) {
            // ignore
            // srcidx++;
            gencode += childDstName + " = 0;\n";
            dstidx++;
            continue;
        } else if(StructType *childStructType = dyn_cast<StructType>(childType)) {
            gencode += writeClCopyNoPtrToPtrfull(childStructType, childSrcName, childDstName);
            srcidx++;
            dstidx++;
        } else if(childType->getPrimitiveSizeInBits() > 0 ) {
            gencode += childDstName + " = " + childSrcName + ";\n";
            // outs() << "copying " << dumpType(childType) << "\n";
            srcidx++;
            dstidx++;
        } else if(ArrayType *arrayType = dyn_cast<ArrayType>(childType)) {
            int numElements = arrayType->getNumElements();
            // outs() << "numlemenets " << numElements << "\n";
            for(int i=0; i < numElements; i++) {
                gencode += childDstName + "[" + easycl::toString(i) + "] = " + childSrcName + "[" + easycl::toString(i) +  "];\n";
            }
            srcidx++;
            dstidx++;
            // throw runtime_error("unhandled type " + dumpType(childType));
        } else {
            outs() << "unhandled type\n";
            childType->dump();
            outs() << "\n";
            // outs() << "unhandled type " + dumpType(childType) << "\n";
            throw runtime_error("unhandled type");
            srcidx++;
            dstidx++;
{'fraction_non_alphanumeric': 0.14452049406026277, 'fraction_numerical': 0.0032255526709149556, 'mean_word_length': 2.8289156626506022, 'pattern_counts': {'":': 0, '<': 115, '<?xml version=': 0, '>': 79, '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': '3701985', 'n_tokens_mistral': 3834, 'n_tokens_neox': 3768, 'n_words': 803}