Esempio n. 1
0
void shortcuts(satinstance sati) {
  int p;

  maxshortcutclauses = 100000;
  nofshortcutclauses = 0;
  shortcutclauses = (shortcutclause *)malloc(maxshortcutclauses * sizeof(shortcutclause));

  for(p=0;p<sati->nOfSVars;p++) {
    shortcutprobe(sati,PLIT(varwithtime(sati,p,flagShortCutHorizon)));
    shortcutprobe(sati,NLIT(varwithtime(sati,p,flagShortCutHorizon)));
  }
#ifdef SHOWIT
  printf("INFERRED %i SHORTCUT CLAUSES.\n",nofshortcutclauses);
#endif
}
Esempio n. 2
0
static GLboolean equality (slang_assemble_ctx *A, slang_operation *op, GLboolean equal)
{
	slang_assembly_typeinfo ti;
	GLboolean result = GL_FALSE;
	slang_storage_aggregate agg;
	GLuint index, size;
	GLuint skip_jump, true_label, true_jump, false_label, false_jump;

	/* get type of operation */
	if (!slang_assembly_typeinfo_construct (&ti))
		return GL_FALSE;
	if (!_slang_typeof_operation (A, op, &ti))
		goto end1;

	/* convert it to an aggregate */
	if (!slang_storage_aggregate_construct (&agg))
		goto end1;
	if (!_slang_aggregate_variable (&agg, &ti.spec, 0, A->space.funcs, A->space.structs,
			A->space.vars, A->mach, A->file, A->atoms))
		goto end;

	/* compute the size of the agregate - there are two such aggregates on the stack */
	size = _slang_sizeof_aggregate (&agg);

	/* jump to the actual data-comparison code */
	skip_jump = A->file->count;
	if (!PUSH (A->file, slang_asm_jump))
		goto end;

	/* pop off the stack the compared data and push 1 */
	true_label = A->file->count;
	if (!PLAB (A->file, slang_asm_local_free, size * 2))
		goto end;
	if (!PLIT (A->file, slang_asm_bool_push, (GLfloat) 1))
		goto end;
	true_jump = A->file->count;
	if (!PUSH (A->file, slang_asm_jump))
		goto end;

	false_label = A->file->count;
	if (!PLAB (A->file, slang_asm_local_free, size * 2))
		goto end;
	if (!PLIT (A->file, slang_asm_bool_push, (GLfloat) 0))
		goto end;
	false_jump = A->file->count;
	if (!PUSH (A->file, slang_asm_jump))
		goto end;

	A->file->code[skip_jump].param[0] = A->file->count;

	/* compare the data on stack, it will eventually jump either to true or false label */
	index = 0;
	if (!equality_aggregate (A, &agg, &index, size, equal ? false_label : true_label))
		goto end;
	if (!PLAB (A->file, slang_asm_jump, equal ? true_label : false_label))
		goto end;

	A->file->code[true_jump].param[0] = A->file->count;
	A->file->code[false_jump].param[0] = A->file->count;

	result = GL_TRUE;
end:
	slang_storage_aggregate_destruct (&agg);
end1:
	slang_assembly_typeinfo_destruct (&ti);
	return result;
}
Esempio n. 3
0
GLboolean _slang_assemble_operation (slang_assemble_ctx *A, slang_operation *op, slang_ref_type ref)
{
	/* set default results */
	A->ref = /*(ref == slang_ref_freelance) ? slang_ref_force : */ref;
	A->swz.num_components = 0;

	switch (op->type)
	{
	case slang_oper_block_no_new_scope:
	case slang_oper_block_new_scope:
		{
			GLuint i;

			for (i = 0; i < op->num_children; i++)
			{
				if (!_slang_assemble_operation (A, &op->children[i], slang_ref_forbid/*slang_ref_freelance*/))
					return GL_FALSE;
				if (!_slang_cleanup_stack (A, &op->children[i]))
					return GL_FALSE;
			}
		}
		break;
	case slang_oper_variable_decl:
		{
			GLuint i;
			slang_operation assign;
			GLboolean result;

			/* Construct assignment expression placeholder. */
			if (!slang_operation_construct (&assign))
				return GL_FALSE;
			assign.type = slang_oper_assign;
			assign.children = (slang_operation *) slang_alloc_malloc (2 * sizeof (slang_operation));
			if (assign.children == NULL)
			{
				slang_operation_destruct (&assign);
				return GL_FALSE;
			}
			for (assign.num_children = 0; assign.num_children < 2; assign.num_children++)
				if (!slang_operation_construct (&assign.children[assign.num_children]))
				{
					slang_operation_destruct (&assign);
					return GL_FALSE;
				}

			result = GL_TRUE;
			for (i = 0; i < op->num_children; i++)
			{
				slang_variable *var;

				var = _slang_locate_variable (op->children[i].locals, op->children[i].a_id, GL_TRUE);
				if (var == NULL)
				{
					result = GL_FALSE;
					break;
				}
				if (var->initializer == NULL)
					continue;

				if (!slang_operation_copy (&assign.children[0], &op->children[i]) ||
					!slang_operation_copy (&assign.children[1], var->initializer) ||
					!_slang_assemble_assign (A, &assign, "=", slang_ref_forbid) ||
					!_slang_cleanup_stack (A, &assign))
				{
					result = GL_FALSE;
					break;
				}
			}
			slang_operation_destruct (&assign);
			if (!result)
				return GL_FALSE;
		}
		break;
	case slang_oper_asm:
		{
			GLuint i;

			if (!_slang_assemble_operation (A, &op->children[0], slang_ref_force))
				return GL_FALSE;
			for (i = 1; i < op->num_children; i++)
				if (!_slang_assemble_operation (A, &op->children[i], slang_ref_forbid))
					return GL_FALSE;
			if (!call_asm_instruction (A, op->a_id))
				return GL_FALSE;
		}
		break;
	case slang_oper_break:
		if (!PLAB (A->file, slang_asm_jump, A->flow.loop_end))
			return GL_FALSE;
		break;
	case slang_oper_continue:
		if (!PLAB (A->file, slang_asm_jump, A->flow.loop_start))
			return GL_FALSE;
		break;
	case slang_oper_discard:
		if (!PUSH (A->file, slang_asm_discard))
			return GL_FALSE;
		if (!PUSH (A->file, slang_asm_exit))
			return GL_FALSE;
		break;
	case slang_oper_return:
		if (A->local.ret_size != 0)
		{
			/* push the result's address */
			if (!PLAB2 (A->file, slang_asm_local_addr, 0, A->local.ret_size))
				return GL_FALSE;
			if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
				return GL_FALSE;

			A->swz.num_components = 0;
			/* assign the operation to the function result (it was reserved on the stack) */
			if (!_slang_assemble_assignment (A, op->children))
				return GL_FALSE;

			if (!PLAB (A->file, slang_asm_local_free, 4))
				return GL_FALSE;
		}
		if (!PLAB (A->file, slang_asm_jump, A->flow.function_end))
			return GL_FALSE;
		break;
	case slang_oper_expression:
		if (ref == slang_ref_force)
			return GL_FALSE;
		if (!_slang_assemble_operation (A, &op->children[0], ref))
			return GL_FALSE;
		break;
	case slang_oper_if:
		if (!_slang_assemble_if (A, op))
			return GL_FALSE;
		break;
	case slang_oper_while:
		if (!_slang_assemble_while (A, op))
			return GL_FALSE;
		break;
	case slang_oper_do:
		if (!_slang_assemble_do (A, op))
			return GL_FALSE;
		break;
	case slang_oper_for:
		if (!_slang_assemble_for (A, op))
			return GL_FALSE;
		break;
	case slang_oper_void:
		break;
	case slang_oper_literal_bool:
		if (ref == slang_ref_force)
			return GL_FALSE;
		if (!PLIT (A->file, slang_asm_bool_push, op->literal))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_literal_int:
		if (ref == slang_ref_force)
			return GL_FALSE;
		if (!PLIT (A->file, slang_asm_int_push, op->literal))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_literal_float:
		if (ref == slang_ref_force)
			return GL_FALSE;
		if (!PLIT (A->file, slang_asm_float_push, op->literal))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_identifier:
		{
			slang_variable *var;
			GLuint size;

			/* find the variable and calculate its size */
			var = _slang_locate_variable (op->locals, op->a_id, GL_TRUE);
			if (var == NULL)
				return GL_FALSE;
			size = 0;
			if (!sizeof_variable (A, &var->type.specifier, slang_qual_none, var->array_len, &size))
				return GL_FALSE;

			/* prepare stack for dereferencing */
			if (ref == slang_ref_forbid)
				if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
					return GL_FALSE;

			/* push the variable's address */
			if (var->global)
			{
				if (!PLAB (A->file, slang_asm_global_addr, var->address))
					return GL_FALSE;
			}
			else
			{
				if (!PLAB2 (A->file, slang_asm_local_addr, var->address, size))
					return GL_FALSE;
			}

			/* perform the dereference */
			if (ref == slang_ref_forbid)
			{
				if (!PUSH (A->file, slang_asm_addr_copy))
					return GL_FALSE;
				if (!PLAB (A->file, slang_asm_local_free, 4))
					return GL_FALSE;
				if (!_slang_dereference (A, op))
					return GL_FALSE;
			}
		}
		break;
	case slang_oper_sequence:
		if (ref == slang_ref_force)
			return GL_FALSE;
		if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid/*slang_ref_freelance*/))
			return GL_FALSE;
		if (!_slang_cleanup_stack (A, &op->children[0]))
			return GL_FALSE;
		if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_assign:
		if (!_slang_assemble_assign (A, op, "=", ref))
			return GL_FALSE;
		break;
	case slang_oper_addassign:
		if (!_slang_assemble_assign (A, op, "+=", ref))
			return GL_FALSE;
		A->ref = ref;
		break;
	case slang_oper_subassign:
		if (!_slang_assemble_assign (A, op, "-=", ref))
			return GL_FALSE;
		A->ref = ref;
		break;
	case slang_oper_mulassign:
		if (!_slang_assemble_assign (A, op, "*=", ref))
			return GL_FALSE;
		A->ref = ref;
		break;
	/*case slang_oper_modassign:*/
	/*case slang_oper_lshassign:*/
	/*case slang_oper_rshassign:*/
	/*case slang_oper_orassign:*/
	/*case slang_oper_xorassign:*/
	/*case slang_oper_andassign:*/
	case slang_oper_divassign:
		if (!_slang_assemble_assign (A, op, "/=", ref))
			return GL_FALSE;
		A->ref = ref;
		break;
	case slang_oper_select:
		if (!_slang_assemble_select (A, op))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_logicalor:
		if (!_slang_assemble_logicalor (A, op))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_logicaland:
		if (!_slang_assemble_logicaland (A, op))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_logicalxor:
		if (!_slang_assemble_function_call_name (A, "^^", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	/*case slang_oper_bitor:*/
	/*case slang_oper_bitxor:*/
	/*case slang_oper_bitand:*/
	case slang_oper_less:
		if (!_slang_assemble_function_call_name (A, "<", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_greater:
		if (!_slang_assemble_function_call_name (A, ">", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_lessequal:
		if (!_slang_assemble_function_call_name (A, "<=", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_greaterequal:
		if (!_slang_assemble_function_call_name (A, ">=", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	/*case slang_oper_lshift:*/
	/*case slang_oper_rshift:*/
	case slang_oper_add:
		if (!_slang_assemble_function_call_name (A, "+", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_subtract:
		if (!_slang_assemble_function_call_name (A, "-", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_multiply:
		if (!_slang_assemble_function_call_name (A, "*", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	/*case slang_oper_modulus:*/
	case slang_oper_divide:
		if (!_slang_assemble_function_call_name (A, "/", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_equal:
		if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
			return GL_FALSE;
		if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
			return GL_FALSE;
		if (!equality (A, op->children, GL_TRUE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_notequal:
		if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
			return GL_FALSE;
		if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
			return GL_FALSE;
		if (!equality (A, op->children, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_preincrement:
		if (!_slang_assemble_assign (A, op, "++", ref))
			return GL_FALSE;
		A->ref = ref;
		break;
	case slang_oper_predecrement:
		if (!_slang_assemble_assign (A, op, "--", ref))
			return GL_FALSE;
		A->ref = ref;
		break;
	case slang_oper_plus:
		if (!_slang_dereference (A, op))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_minus:
		if (!_slang_assemble_function_call_name (A, "-", op->children, 1, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	/*case slang_oper_complement:*/
	case slang_oper_not:
		if (!_slang_assemble_function_call_name (A, "!", op->children, 1, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_subscript:
		{
			slang_assembly_typeinfo ti_arr, ti_elem;

			if (!slang_assembly_typeinfo_construct (&ti_arr))
				return GL_FALSE;
			if (!slang_assembly_typeinfo_construct (&ti_elem))
			{
				slang_assembly_typeinfo_destruct (&ti_arr);
				return GL_FALSE;
			}
			if (!handle_subscript (A, &ti_elem, &ti_arr, op, ref))
			{
				slang_assembly_typeinfo_destruct (&ti_arr);
				slang_assembly_typeinfo_destruct (&ti_elem);
				return GL_FALSE;
			}
			slang_assembly_typeinfo_destruct (&ti_arr);
			slang_assembly_typeinfo_destruct (&ti_elem);
		}
		break;
	case slang_oper_call:
		{
			slang_function *fun;

			fun = _slang_locate_function (A->space.funcs, op->a_id, op->children, op->num_children,
				&A->space, A->atoms);
			if (fun == NULL)
			{
				if (!_slang_assemble_constructor (A, op))
					return GL_FALSE;
			}
			else
			{
				if (!_slang_assemble_function_call (A, fun, op->children, op->num_children, GL_FALSE))
					return GL_FALSE;
			}
			A->ref = slang_ref_forbid;
		}
		break;
	case slang_oper_field:
		{
			slang_assembly_typeinfo ti_after, ti_before;

			if (!slang_assembly_typeinfo_construct (&ti_after))
				return GL_FALSE;
			if (!slang_assembly_typeinfo_construct (&ti_before))
			{
				slang_assembly_typeinfo_destruct (&ti_after);
				return GL_FALSE;
			}
			if (!handle_field (A, &ti_after, &ti_before, op, ref))
			{
				slang_assembly_typeinfo_destruct (&ti_after);
				slang_assembly_typeinfo_destruct (&ti_before);
				return GL_FALSE;
			}
			slang_assembly_typeinfo_destruct (&ti_after);
			slang_assembly_typeinfo_destruct (&ti_before);
		}
		break;
	case slang_oper_postincrement:
		if (!assemble_function_call_name_dummyint (A, "++", op->children))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_postdecrement:
		if (!assemble_function_call_name_dummyint (A, "--", op->children))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	default:
		return GL_FALSE;
	}

	return GL_TRUE;
}
Esempio n. 4
0
void shortcutprobe(satinstance sati,int l) {
  int i,l2;
  PTRINT reason;

#ifdef HARDDEBUG
  printf("--------------------------------------------------------------\n");
#endif

  for(i=0;i<sati->nOfVars;i++) {
    int flag;
    flag=0;
    if(!varunsetp(sati,i)) {
      printf("INCORRECTLY ALREADY SET: %i",i); printTlit(sati,PLIT(i));
      flag = 1;
    }
    assert(flag==0);
  }

  setUPstacktop(sati,-1); /* Drop the input unit clauses from the stack. */
  sati->dlevel = 0;

  sati->declevels[0] = 0;

#ifdef HARDDEBUG
  printf("Trying ");
  printTlit(sati,l);
  printf("\n");
#endif

  simpleaddtoqueue(sati,l,REASON_DECISION,0);

  if(propagate(sati)) {
    // Literal cannot be true.
#ifdef SHOWIT
    printf("CONTRADICTION WITH ");
    printTlit(sati,l);
    printf("\n");
#endif
    undo_assignments_until_level_NOHEAP(sati,0);
    return;
  }

  //  printf("PROPAGATED\n");

  for(i=1;i<sati->endunitstack;i++) {   // Go through inferred literals.

    l2 = sati->unitstack[i];

    reason = LITREASON(l2);

#ifdef HARDDEBUG
    printf("Checking %i:",i); printTlit(sati,l2);
    printf("   REASON: ");
    if(reason == REASON_INPUT) printf("INPUT");
    else if(reason == REASON_DECISION) printf("DECISION");
    else if((reason&1)==0) printf(" LONG CLAUSE");
    else printTlit(sati,reason >> 1);
			      
    printf("\n");
#endif

    if((reason & 3) == 0 && clauselen((int *)reason) > 3) { // Reason is a long clause?
      // Store the new binary literal for later use.
      if(nofshortcutclauses+1 >= maxshortcutclauses) {
	maxshortcutclauses = maxshortcutclauses * 2;
	shortcutclauses = (shortcutclause *)realloc(shortcutclauses,
						    maxshortcutclauses * sizeof(shortcutclause));
      }

      shortcutclauses[nofshortcutclauses].l1 = NEG(l) % (2 * sati->nOfVarsPerTime);
      shortcutclauses[nofshortcutclauses].l2 = l2 % (2 * sati->nOfVarsPerTime);
      shortcutclauses[nofshortcutclauses++].tdiff = tvartime(sati,VAR(l2))-tvartime(sati,VAR(l));

#ifdef SHOWIT
      printf("INFER CLAUSE: ");
      printTlit(sati,shortcutclauses[nofshortcutclauses-1].l1);
      printf(" V ");
      printlit(shortcutclauses[nofshortcutclauses-1].l2);
      printf("@%i (through length %i)\n",shortcutclauses[nofshortcutclauses-1].tdiff,clauselen((int *)reason));
#endif
    }

  }
  undo_assignments_until_level_NOHEAP(sati,0);

  for(i=0;i<sati->nOfVars;i++)
    if(!varunsetp(sati,i)) {
      printf("INCORRECTLY REMAINS SET: %i",i); printTlit(sati,PLIT(i));
      assert(1==0);
    }
}