#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
int /*<<< orphan*/ printf(char *, char *);
void generate_macro_mul_matrix() {
  char *s =
      "void* mul_matrix(char const* param_type, int** mat_1, int**  mat_2, int "
      "mat_1_rows, int mat_1_cols, int mat_2_rows, int mat_2_cols) { 	int i, "
      "j, k;	if(strcmp(\"int\", param_type) == 0) {		int** "
      "mat;		int sum;		//alloco lo spazio per la "
      "matrice da ritornare		//ed effettuo nel contempo "
      "l'operazione di somma		mat = calloc(mat_1_rows, "
      "sizeof(void*));		for(i=0; i<mat_1_rows; i++) {		"
      "	mat[i] = calloc(mat_2_cols, sizeof(int));			"
      "for(j=0; j<mat_2_cols; j++ ) {				//imposto la "
      "somma parziale a 0				sum = 0;	"
      "			for(k = 0; k < mat_1_cols; k++) {		"
      "			sum += mat_1[i][k] * mat_2[k][j];		"
      "		}				mat[i][j] = sum;	"
      "		}		}				return "
      "mat;	}	else {		double** mat;		double "
      "sum;		//alloco lo spazio per la matrice da ritornare	"
      "	//ed effettuo nel contempo l'operazione di somma		mat = "
      "calloc(mat_1_rows, sizeof(void*));		for(i=0; i<mat_1_rows; "
      "i++) {			mat[i] = calloc(mat_2_cols, "
      "sizeof(double));			for(j=0; j<mat_2_cols; j++ ) {	"
      "			//imposto la somma parziale a 0			"
      "	sum = 0;				for(k = 0; k < mat_1_cols; "
      "k++) {					sum += mat_1[i][k] * "
      "mat_2[k][j];					}		"
      "		mat[i][j] = sum;			}		"
      "}				return mat;	}}\n";
  printf("%s\n", s);
}


x86 assembly (clang, -O0):
<generate_macro_mul_matrix>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
lea    0xee1(%rip),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rsi
lea    0x1310(%rip),%rdi
call   1030 <printf@plt>
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<generate_macro_mul_matrix>:
lea    0x1327(%rip),%rdi
lea    0xee2(%rip),%rsi
jmp    1030 <printf@plt>

LLVM IR (-O0):
@.str = [1086 x i8] c"void* mul_matrix(char const* param_type, int** mat_1, int** mat_2, int mat_1_rows, int mat_1_cols, int mat_2_rows, int mat_2_cols) { \09int i, j, k;\09if(strcmp(\22int\22, param_type) == 0) {\09\09int** mat;\09\09int sum;\09\09//alloco lo spazio per la matrice da ritornare\09\09//ed effettuo nel contempo l'operazione di somma\09\09mat = calloc(mat_1_rows, sizeof(void*));\09\09for(i=0; i<mat_1_rows; i++) {\09\09\09mat[i] = calloc(mat_2_cols, sizeof(int));\09\09\09for(j=0; j<mat_2_cols; j++ ) {\09\09\09\09//imposto la somma parziale a 0\09\09\09\09sum = 0;\09\09\09\09for(k = 0; k < mat_1_cols; k++) {\09\09\09\09\09sum += mat_1[i][k] * mat_2[k][j];\09\09\09\09}\09\09\09\09mat[i][j] = sum;\09\09\09}\09\09}\09\09\09\09return mat;\09}\09else {\09\09double** mat;\09\09double sum;\09\09//alloco lo spazio per la matrice da ritornare\09\09//ed effettuo nel contempo l'operazione di somma\09\09mat = calloc(mat_1_rows, sizeof(void*));\09\09for(i=0; i<mat_1_rows; i++) {\09\09\09mat[i] = calloc(mat_2_cols, sizeof(double));\09\09\09for(j=0; j<mat_2_cols; j++ ) {\09\09\09\09//imposto la somma parziale a 0\09\09\09\09sum = 0;\09\09\09\09for(k = 0; k < mat_1_cols; k++) {\09\09\09\09\09sum += mat_1[i][k] * mat_2[k][j];\09\09\09\09\09}\09\09\09\09mat[i][j] = sum;\09\09\09}\09\09}\09\09\09\09return mat;\09}}\0A\00"
@.str.1 = [4 x i8] c"%s\0A\00"
define void @generate_macro_mul_matrix() {
%1 = alloca i8*
store i8* getelementptr inbounds ([1086 x i8], [1086 x i8]* @.str, i64 0, i64 0), i8** %1
%2 = load i8*, i8** %1
%3 = call i32 @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i64 0, i64 0), i8* %2)
ret void
}

LLVM IR (-O2):
@.str = [1086 x i8] c"void* mul_matrix(char const* param_type, int** mat_1, int** mat_2, int mat_1_rows, int mat_1_cols, int mat_2_rows, int mat_2_cols) { \09int i, j, k;\09if(strcmp(\22int\22, param_type) == 0) {\09\09int** mat;\09\09int sum;\09\09//alloco lo spazio per la matrice da ritornare\09\09//ed effettuo nel contempo l'operazione di somma\09\09mat = calloc(mat_1_rows, sizeof(void*));\09\09for(i=0; i<mat_1_rows; i++) {\09\09\09mat[i] = calloc(mat_2_cols, sizeof(int));\09\09\09for(j=0; j<mat_2_cols; j++ ) {\09\09\09\09//imposto la somma parziale a 0\09\09\09\09sum = 0;\09\09\09\09for(k = 0; k < mat_1_cols; k++) {\09\09\09\09\09sum += mat_1[i][k] * mat_2[k][j];\09\09\09\09}\09\09\09\09mat[i][j] = sum;\09\09\09}\09\09}\09\09\09\09return mat;\09}\09else {\09\09double** mat;\09\09double sum;\09\09//alloco lo spazio per la matrice da ritornare\09\09//ed effettuo nel contempo l'operazione di somma\09\09mat = calloc(mat_1_rows, sizeof(void*));\09\09for(i=0; i<mat_1_rows; i++) {\09\09\09mat[i] = calloc(mat_2_cols, sizeof(double));\09\09\09for(j=0; j<mat_2_cols; j++ ) {\09\09\09\09//imposto la somma parziale a 0\09\09\09\09sum = 0;\09\09\09\09for(k = 0; k < mat_1_cols; k++) {\09\09\09\09\09sum += mat_1[i][k] * mat_2[k][j];\09\09\09\09\09}\09\09\09\09mat[i][j] = sum;\09\09\09}\09\09}\09\09\09\09return mat;\09}}\0A\00"
@.str.1 = [4 x i8] c"%s\0A\00"
define void @generate_macro_mul_matrix() {
%1 = tail call i32 @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i64 0, i64 0), i8* getelementptr inbounds ([1086 x i8], [1086 x i8]* @.str, i64 0, i64 0))
ret void
}